Marcin Doliwa Marcin Doliwa - 6 months ago 12
jQuery Question

Calling function within prototype

I'm starting learning OOP in javascript and got stuck with this problem.
I have simple object:

function Notifications() {
this.button = $('#dLabel');
this.wrapper = $('#notifications');
this.elements = [];
}

Notifications.prototype = {
constructor: Notifications,
fetch: function() {
$.ajax({
method: "GET",
url: '/notifications.json'
}).done(function(data) {
this.elements = data;
this.refresh();
});
},
refresh: function() {
console.log("REFRESH");
}
}


$(function() {
var ns = new Notifications();

ns.fetch();
})


When I run this I get:

Uncaught TypeError: this.refresh is not a function


Is it becasue
this
in
.done
function is not
Notifications
instance? How can I fix this ?

Answer

Use the bind() method to fix the context:

Notifications.prototype = {
  constructor: Notifications,
  fetch: function() {
    $.ajax({
      method: "GET",
      url: '/notifications.json'
    }).done(function(data) {
      this.elements = data;
      this.refresh();
    }.bind(this)); // <------- Use bind(this)
  },
  refresh: function() {
    console.log("REFRESH");
  }
}

The done() handler function(data) {...} is executed as a simple function invocation, which has the context this as the global object (Window) or undefined in "strict mode".
The Function.prototype.bind(newContent) modifies the context to newContext.

This section describes in more details how this can be lost and how to prevent that.