Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

tayjohn
PLUS
tayjohn
Courses Plus Student 1,595 Points

Calling a defined function from a callback function

I have a function defined like this:

this.notifyObservers = function(obj) {
    for (var i = 0; i < this.observer.length; i++){
        this.observer[i](this, obj); //observer array is defined earlier in the code
    }
}

Now I have an ajax call in another function that takes a callback function as one of it's parameters:

this.getDish = function (id, cb) {
    $.ajax( {
      ...
        success: function(data) {
            cb(data);
        }
      ...
  )
}

Now when I call this.getDish, I would like to call this.notifyObservers like this:

    this.getDish(id, function(data) {
        ...
        this.notifyObservers(this);
        ...
    });

However I keep getting a typeError that notifyObservers is not a function:

 Uncaught TypeError: this.notifyObservers is not a function

My assumption is that it has something to do with the scope, but could someone explain it further? And how could I go to solve this?

(The "..." notation is meant to mean omitted code)

2 Answers

Thomas Nilsen
Thomas Nilsen
14,957 Points

Your mistake is here;

 this.getDish(id, function(data) {
        ...
        this.notifyObservers(this); //the first 'this' on the line doesn't refer to the 'this' you think
        ...
    });

Here is a small example to demonstrate the difference;

var myObject = {
    whatsThis: function() {
        console.log(this); //here - 'this' refers to 'myObject'
        function whatsThisThen() {
            console.log(this); //here - 'this' does NOT refer to 'myObject', but the global object
         }
        whatsThisThen();
    }
}

myObject.whatsThis();

So having looked very fast through your code, you should be able to do something like this;

this.getDish(id, function(data) {
        ...
        this.notifyObservers(this);
        ...
    }.bind(this)); //Sets it to the correct 'this'

Working with this - is always fun.

Also - this is a very good article when it comes to understanding 'this' as well as a few other native javascript-methods.

tayjohn
tayjohn
Courses Plus Student 1,595 Points

Thank you for your detailed response.

After further research, another trick I found out was declaring a variable outside the function that points to "this" as in the global object.

Regarding the example you provided:

var myObject = {
    whatsThis: function() {
        console.log(this); //here - 'this' refers to 'myObject'
        function whatsThisThen() {
            console.log(this); // How come this does not refer to myObject anymore?
         }
        whatsThisThen();
    }
}

myObject.whatsThis();

How come the "this" in the whatsThisThen() doesn't refer to myObject anymore? myObject contains a property whatsThis that contains a function. The first "this" refers to myObject which makes sense.

But the second "this" in whatsThisThen is still part of the property "whatsThis" that is part of myObject.. So why wouldn't it refer back to myObject but instead back to the global object?