5

I have some code to get calendar events and display them. The display is only updated if the events have changed, since the last call.

var calendar = {

    events = null,

    display_calendar_events : function (data) {
        // Some display stuff...
    },

    get_events: function() {

        // Get messages for calendar
        $.getJSON("/ajax/get-events/", function(json){

            var new_events = json.data;
            // If events haven't changed, do nothing
            if (this.events === new_events) {
                return true;
            }

            // Events have changed. 
            // Save new events
            this.events = new_events;

            // Display new events
            this.display_calendar_events(json);
        });
   },
}

I call this with:

calendar.get_queued_events();

The problem is, I'm getting the error "this.display_calendar_events is not a function" (last line of code). But if I change this line to:

calendar.display_canendar_events(josn)

it works. The storing of the old events with "this.events" works fine in both cases.

Can someone explain this to me? How can "this" work for some stuff and not others? Thanks.

2

2 Answers 2

10

In a jQuery AJAX callback, this references the ajax request object. Try using var self = this; before your AJAX call, and in the callback use self.display_calendar_events().

Alternatively, you could just reference calendar.display_calendar_events() directly. But that's not easily refactored like the self method is.

Sign up to request clarification or add additional context in comments.

3 Comments

This isn't really anything to do with jQuery or AJAX, this is simply the way closures work in JavaScript.
This explains why it's failing. Thanks. But why does this.events still work? Shouldn't this fail for the same reason?
@Aine this.events is a property, not a method. Javascript objects are dynamic, so when you check this.events you just get undefined, and setting this.events creates a new property on this.
2

When you call this.display_calendar_events() inside the ajax request you area ctually in a different context than your object. You have to do:

var calendar = {

events = null,

display_calendar_events : function (data) {
    // Some display stuff...
},

get_events: function() {
    var $this = this; 
    // Get messages for calendar
    $.getJSON("/ajax/get-events/", function(json){

        var new_events = json.data;
        // If events haven't changed, do nothing
        if ($this.events === new_events) {
            return true;
        }

        // Events have changed. 
        // Save new events
        $this.events = new_events;

        // Display new events
        $this.display_calendar_events(json);
    });

   },

}

2 Comments

I suggest to add comments instead of using **.
You are right, that's why I never downvote for such little things, but leave a comment instead. Anyways, to avoid such situations, test your code before you post it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.