-1

I've read the similar questions on SO and can't figure out what I'm doing wrong. I can't call the prototype method from within the constructor method. I get: Uncaught TypeError: Object # has no method 'afterLoad'

var FiltersByDivision = function () {
   $(document).on('afterLoad', this.afterLoad());
};

FiltersByDivision.prototype.afterLoad = function (){
   console.log('afterLoad');
}

function OpenOrders() {
  Widget.call(this);
  FiltersByDivision.call(this);
  this.widgetEndpoint = '/xxxxx';
}

OpenOrders.prototype = Object.create(Widget.prototype);
OpenOrders.prototype.constructor = OpenOrders;
  • 1
    Are you creating a new `OpenOrders` object with `new`? `var x = new OpenOrders();`? And, why are you calling `FiltersByDivision` which you do not inherit from? – jfriend00 Mar 30 '15 at 15:27
  • Yes, with new as in var x = new OpenOrders(); – rabbitfeetz Mar 30 '15 at 15:32
  • 3
    Where is any code that inherits from `FiltersByDivision`? Your `OpenOrders` object will not have any methods from the `FiltersByDivision` prototype because you never did anything to inherit from that object or to add those methods to your object. – jfriend00 Mar 30 '15 at 15:36
  • 2
    Also note that you're currently binding the `afterload` event to the _result of calling_ `this.afterLoad()` (currently `undefined`), not to the function itself. – James Thorpe Mar 30 '15 at 15:41

2 Answers2

1

There are a number of problems with this code:

  1. You aren't inheriting from FiltersByDivision so thus an OpenOrders object does not have any FiltersByDivision methods. That's the reason why there is no afterLoad method.

  2. $(document).on('afterLoad', this.afterLoad()); will execute this.afterLoad() immediately and pass it's return result as the event handler (which is not what you want). After you fix item 1, perhaps, you want $(document).on('afterLoad', this.afterLoad.bind(this));

There are many possible structures here. If FiltersByDivision is a separate object, then perhaps OpenOrders should just have one of those objects in its instance data like this (though if all it is doing is setting up an event handler, I'm not sure why it is a separate type of object):

var FiltersByDivision = function () {
   $(document).on('afterLoad', this.afterLoad.bind(this));
};

FiltersByDivision.prototype.afterLoad = function (){
   console.log('afterLoad');
}

function OpenOrders() {
    Widget.call(this);
    this.filter = new FiltersByDivision();
    this.widgetEndpoint = '/xxxxx';
}

OpenOrders.prototype = Object.create(Widget.prototype);
OpenOrders.prototype.constructor = OpenOrders;
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Do you know anywhere that explains #1? I've been surprisingly unlucky in searching for a good explanation of prototype inheritance. – rabbitfeetz Mar 30 '15 at 16:11
  • 1
    @NeilKempin - we'd need to understand more about what you're really trying to do as there are several different approaches depending upon the specific needs and structure/organization of objects and inheritance. See one such idea I added to my answer. – jfriend00 Mar 30 '15 at 21:32
  • 1
    @NeilKempin you could try the link posted in my answer. If anything is unclear there you can comment on that question – HMR Mar 31 '15 at 00:07
0

As jsfriend already pointed out is that afterLoad is not on ObjectOrders prototype. Doing a OtherConstructor.call does not inherit that constuctors prototype but initializes instance variables.

The value of this is the invoking object so the declaration of the function doesn't define its value but how you invoke it. You could use closures:

var FiltersByDivision = function () 
   var me = this;
   $(document).on('afterLoad', function(){
      me.afterLoad();
    });
 };

More info on this, prototype and closures can be found here: https://stackoverflow.com/a/16063711/1641941

Community
  • 1
  • 1
HMR
  • 37,593
  • 24
  • 91
  • 160