0

I am trying to call a prototype method from a jquery event handler. I have the code like this:

$('#' + this.ID + ' .selMake').on('change', this.getCarModel());

I get an error saying: Uncaught TypeError: Object [object global] has no method 'getCarModel'

What am I doing wrong here?

user3312508
  • 907
  • 4
  • 10
  • 25
  • @wootscootinboogie No it isn't, since that code isn't in a callback function. – Barmar Sep 09 '14 at 20:29
  • 1
    Related: http://stackoverflow.com/questions/24173440/save-access-to-this-scope – Travis J Sep 09 '14 at 20:35
  • 1
    You must pass a function to `.on()`, not the result of a call! – Bergi Sep 09 '14 at 20:35
  • Can you please show the full code, including the surrounding function? – Bergi Sep 09 '14 at 20:37
  • @Bergi Added the full code – user3312508 Sep 09 '14 at 20:40
  • @user3312508: You don't even have created an instance of `vehicleSelect`! – Bergi Sep 09 '14 at 20:41
  • @Bergi I have its in a different js file.Is it possible to add event listener to the object? – user3312508 Sep 09 '14 at 20:43
  • @user3312508: Please show that part as well. You need to use the variable with the instance, not `this`. The `$('#' + this.ID + ' .selMake').on('change', this.getCarModel);` should go in that file as well (or, if you want to execute it for all instance, in the constructor). Placing it outside of everything doesn't make sense. – Bergi Sep 09 '14 at 20:45

3 Answers3

1

The first thing you need to do is remove the parentheses from the function. What your code is currently expecting is for getCarModel to return a function which is then being called when the event is triggered.

It looks like this is what you would like to do:

 $('#' + this.ID + ' .selMake').on('change', that.getCarModel);

Not this:

 $('#' + this.ID + ' .selMake').on('change', that.getCarModel());

If you want to call the function that way, you can do as follows:

 var that = this;
 $('#' + this.ID + ' .selMake').on('change', function () {
     that.getCarModel();
 });

Above, you are passing an anonymous function as an argument which will execute the code inside of it.

In the functions above, the definition of this will depend on the element that triggered the event. If you want the definition of this to be tied to your this object, you can do the following:

The most simple, understandable way is to use the that variable:

var that; 
$('#' + this.ID + ' .selMake').on('change', that.getCarModel); // This will execute the function this.getcarModel

You can also use the bind method in browsers that support ES5.

$('#' + this.ID + ' .selMake').on('change', this.getCarModel.bind(this));
Jorge Silva
  • 4,574
  • 1
  • 23
  • 42
1

The second argument to .on() should be a function. You're calling the function when you bind the handler, not when the event occurs. It should be:

var self = this;
$('#' + this.ID + " .selMake').on('change', function() {
    self.getCarModel();
});

You need to use the local variable self so this will be saved in the closure. See

"this" keyword in event methods when using JavaScript prototype object

for details about this.

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

Use this code:

vehicleSelect.prototype.getCarMakes = function() {
  // Optional parameters
  var options = {};

  var select = $('#' + this.ID + ' .selMake'),
      that = this;

  select.on('change', function(e) {
    that.getCarModel();
  });

  // Callback function to be called when the API response is returned
  function success(res) {
    for (var i=0; i<res.makes.length; i++) {
      $("<option>",{
        value: res.makes[i].niceName,
        html: res.makes[i].name
      }).appendTo(select);
    }
    select.removeAttr("disabled");
    select + $(' option[value="placeholder"]').html('Select Make');
  }
  // Oops, we have a problem!
  function fail(data) { console.log(data); }
  // Fire the API call
  this.res.api('/api/vehicle/v2/makes', options, success, fail);
};

For why you can't just use select.on('change', this.getCarModel) see this question (which also provides alternative solutions).

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375