Friday, February 17, 2012

this.function is not a function error, but function exists


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 comments:

  1. 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.

    ReplyDelete
  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);
    });

    },

    }

    ReplyDelete