I'm having difficulty with Javascript instance variables. I'm trying to make an easy way to refresh the chat page, looking for new messages. The AJAX call supplies a mid
, or the lowest message id to be returned. This allows the call to only ask for the most recent messages, instead of all of them.
MessageRefresher.prototype._latest_mid;
function MessageRefresher(latest_mid) {
this._latest_mid = latest_mid; // it thinks `this` refers to the MessageRefresher object
}
MessageRefresher.prototype.refresh = function () {
refreshMessages(this._latest_mid); // it thinks `this` refers to the window
this._latest_mid++;
}
function refreshMessages(latest_mid) {
$.getJSON('API/read_messages', { room_id: $.getUrlVar('key'), mid: latest_mid }, function (messages) {
for (var i = 0; i < messages[0].length; i++) {
var newChild = sprintf("<li>%s: %s</li>", messages[1][i], messages[0][i]);
$("#messages").append(newChild);
}
});
var messageRefresher = new MessageRefresher(0);
setInterval(messageRefresher.refresh, 1000);
This results in all the messages being printed out, over and over again.
I know it has other bugs, but the main issue I'm trying to work out right now is the use of the instance variable. Or is there another way I should be going about doing this?
UPDATE: Updated code to reflect answers, but it still doesn't work:
$(document).ready(function () {
var messageRefresher = new MessageRefresher(0);
setInterval($.proxy(messageRefresher, "refresh"), 1000);
});
function MessageRefresher(latest_mid) {
this._latest_mid = latest_mid; // it thinks `this` refers to the MessageRefresher object
}
MessageRefresher.prototype.refresh = function () {
refreshMessages(this._latest_mid); // it thinks `this` refers to the window
}
function refreshMessages(latest_mid) {
var refresher = this;
$.getJSON('API/read_messages', { room_id: $.getUrlVar('key'), mid: latest_mid }, function (messages) {
if (messages != null) {
$("#messages-loading-msg").hide();
for (var i = 0; i < messages[0].length; i++) {
var newChild = sprintf("<li>%s: %s</li>", messages[1][i], messages[0][i]);
$("#messages").append(newChild);
}
}
else {
$("#messages-loading-msg").text("No messages here. Say anything...");
}
refresher._latest_mid = messages[2];
});
}
What am I still doing wrong? Does this
really refer to the messageRefresher
, or to the proxy
?
UPDATE 2: Getting closer, but still not quite there:
$(document).ready(function () {
$("#no-js-warning").empty();
messageRefresher = new MessageRefresher(0);
setInterval($.proxy(messageRefresher, "refresh"), 1000);
});
function MessageRefresher(latest_mid) {
this._latest_mid = latest_mid;
}
MessageRefresher.prototype.refresh = function () {
var refresher = this;
$.getJSON('API/read_messages', { room_id: $.getUrlVar('key'), mid: refresher._latest_mid }, function (messages) {
if (messages != null) {
$("#messages-loading-msg").hide();
for (var i = 0; i < messages[0].length; i++) {
var newChild = sprintf("<li>%s: %s</li>", messages[1][i], messages[0][i]);
$("#messages").append(newChild);
}
}
else {
$("#messages-loading-msg").text("No messages here. Say anything...");
}
refresher._latest_mid = messages[2]; // break here
});
}
The above code makes two AJAX calls, then stops. Also, when I break on the "break here" line labeled above, Firebug does not show values for refresher
or _latest_mid
. Am I passing refresher
into the closure correctly?
UPDATE 3: Now it no longer stops making AJAX calls. Perhaps the reason that it sometimes makes multiple calls is that setInterval()
fires off multiple requests before the first request has returned and has updated _latest_mid
.
How can I use the JQuery Ajax framework to prevent this from happening?