Orkun
Orkun

Reputation: 7228

Object function () { } has no method 'my method'

i am using a method (searchTransportation) for an event callback.

exports.searchTransportation = function (items, num, UrlS) {
//...
}

exports.doHotelInsertion = function(items, num, typetransport, UrlS, callback) {
  // (omitted code)


  event.on("STARTWITHAIRSEARCH" + num, searchTransportation ); //!!! causes error

};

I tried smth like

  event.on("STARTWITHAIRSEARCH" + num, this.searchTransportation(items, num,
          UrlS).bind(this));

But this is breaking code and ends up with Object function () { } has no method 'searchTransportation'

I understand that the event callback is at the global scope but is there a way to call an existing method?

-- EDIT

this is a bit like this SO question : Class methods as event handlers in javascript but with a nodejs twist. What s the most elegant way of doing this?

Upvotes: 3

Views: 78

Answers (2)

ralzaul
ralzaul

Reputation: 4470

What is happening is that your callback is called before your event.on function calls for the this.searchTransportation.bind(...).

So basically you are losing your valid this pointer since the function has terminated already. this pointer is no more referring to a valid object (probably your object goes out of scope and is cleaned from the memory).

You have two options to solve this problem: 1st one is to create local variables which will be stored till the end of the async call :

exports.doHotelInsertion = function(items, num, typetransport, UrlS, callback) {

  var _items = items;
  var _num = num;
  var _UrlS = UrlS; 
  var localthis = this;

  event.on("STARTWITHAIRSEARCH" + num, localthis.searchTransportation(_items, _num, _UrlS));
};

2nd and more elegant one would be to bind the variables as parameters to your async call for them to be preserved.

exports.doHotelInsertion = function(items, num, typetransport, UrlS, callback) {

  // somestuff
  var localthis = this;

  event.on("STARTWITHAIRSEARCH" + num, localthis.searchTransportation(items, num, UrlS));
};

You still have to create a local variable for this but at least for the others it will be tidier.

Upvotes: 3

epascarello
epascarello

Reputation: 207511

I am guessing that searchTransportation does not return a function, so your bind line should look like this

event.on("STARTWITHAIRSEARCH" + num, this.searchTransportation.bind(this, items, num, UrlS));

MDN: fun.bind(thisArg\[, arg1\[, arg2\[, ...\]\]\])

Upvotes: 2

Related Questions