0

Im getting an Uncaught TypeError: Cannot read property 'target' of undefined when calling widget.Test() in the beforeAppear.

define(
          //-------------------------------------------------------------------
          // DEPENDENCIES
          //-------------------------------------------------------------------
        ['knockout'],

        // -------------------------------------------------------------------
        // MODULE DEFINITION
        // -------------------------------------------------------------------
        function (ko) {

        "use strict";

        return {

            First_Arr: ko.observableArray(['arrayItem0', 'arrayItem1', 'arrayItem2', 'arrayItem3']),
            Second_Arr: ko.observableArray(['arrayItem0', 'arrayItem1', 'arrayItem2']),

            Test: function(widget, event) {            

                var element = event.target;          
                var pathname = location.pathname;
                var anotherArray = [
                    ["/some-url-path", widget.First_Arr()],
                    ["/some-other-url-path", widget.Second_Arr()]
                ];

                for (var i = 0; i < anotherArray.length; i++) {
                    // Do some stuff and console.log the array items                        
                }

            },

            beforeAppear: function(page) {

                var widget = this;
                widget.Test();

            }
        }
    }
);

The strange thing is, if I create a button in my view for example:

<button id="btn-click" data-bind="click: Test">test</button>

And click it, then I get the desired results of printing out the contents of my array to the console as expected.

PS. I tried commenting out the var element = event.target; line since I figured this was the source of the problem however this just produced the following: Uncaught TypeError: Cannot read property 'First_Arr()' of undefined.

A bit at a loss with this one. Any assistance would be helpful.

1 Answers1

0

When you call widget.Test() you aren't passing it an event parameter so event will be undefined and event.target will error because target doesn't exist on "undefined". In a click binding the click "event" is automatically passed into the function.

The second issue is that var widget = this; is essentially setting widget = beforeAppear;. Within a function "this" refers to the function itself. See How does the "this" keyword work?

Instead of defining your module as an object literal you might have better luck using a constructor function instead. See Should I be using object literals or constructor functions?

That would probably look something like:

define(
          //-------------------------------------------------------------------
          // DEPENDENCIES
          //-------------------------------------------------------------------
        ['knockout'],

        // -------------------------------------------------------------------
        // MODULE DEFINITION
        // -------------------------------------------------------------------
        function (ko) {

        "use strict";

        return function(){
            var self = this;

            self.First_Arr = ko.observableArray(['arrayItem0', 'arrayItem1', 'arrayItem2', 'arrayItem3']);
            self.Second_Arr = ko.observableArray(['arrayItem0', 'arrayItem1', 'arrayItem2']);

            self.Test = function(widget, event) { 
                var element = event.target;          
                var pathname = location.pathname;
                var anotherArray = [
                    ["/some-url-path", self.First_Arr()],
                    ["/some-other-url-path", self.Second_Arr()]
                ];

                for (var i = 0; i < anotherArray.length; i++) {
                    // Do some stuff and console.log the array items                        
                }    
            }

            self.beforeAppear = function(page) {
                //var widget = this;
                self.Test();    
            }
        }();
    }
);
Community
  • 1
  • 1
Jason Spake
  • 4,224
  • 2
  • 14
  • 22