views:

343

answers:

1

Hi all, I'm writing a userscript for a website that uses Prototype. Rather than use the GM libs (mainly so I can easily repurpose it for Chrome), I decided to use the already-loaded Prototype functions.

I'm iterating through the rows of a table, each signifying a unique user, by checking for an online status element on their profile page.

dom = unsafeWindow; //shortening unsafewindow

console.log("main start");
var rows = dom.$$("#users tbody>tr");
var users = dom.$$("#users tbody>tr .user_avatar");
console.log(rows);
for (var i=0; i < users.length; i++) {
    var row = rows[i];
    var user = users[i];
    new dom.Ajax.Request("/users/" + user["title"] + ".html", { //user["title"] is the username
            method:'get',
            onSuccess:     function(response) {
                                var state = "offline";
                                if (response.responseText.indexOf("now_online") > -1) {
                                    state = "online";
                                }
                                row.childElements()[1].innerHTML += "<br /><b>" + state + "</b>";
                        }, 
            onFailure:    function(request) {
                            row.childElements()[1].innerHTML += "<br /><b>Error</b>";
                        }
        }
    );
}

Observing the script executing in Firebug, I see all of the GETs return valid response bodies with a status of 200. However, "online" only gets displayed in the last row. It appears as if the callbacks for the previous rows aren't being called. I have verified this with console.log statements after each line.

I searched and found that there were issues with how FB and Firefox 3.5 handled multiple Ajax.Requests http://code.google.com/p/fbug/issues/detail?id=1948. I upgraded to the most recent beta of Firebug and have the most recent non-beta version of Firefox, and still no dice. The problem occurs even when I have FB disabled completely.

I'm pretty much drawing a blank at this point, so I'm open to any and all suggestions. Thanks.

A: 

try using function.bind() to set the scope/prepend a variable.

        onSuccess:     function(response) {
                            var state = "offline";
                            if (response.responseText.indexOf("now_online") > -1) {
                                state = "online";
                            }
                            arguments[0].innerHTML += "<br /><b>" + state + "</b>";
                    }.bind(this,row),

EDIT: or check out This Way Of Doing It

Dereleased
I can't bind to a function like that. The only binding technique that could possibly work in these circumstances is if I could do ajaxReq.onSuccess.bind(this, row), but the minute I instantiate onSuccess, the request gets made.
Aru
I'm sorry, I don't understand why you can't bind like this; the function "bind" returns a functor, which is exactly what the onSuccess argument is expecting.
Dereleased
I can't call bind like this function(param) { ... }.bind(scope vars), I get js errors.
Aru
That is very strange, I have used that convention many times with no errors, mind sharing what browser/version this is on? Also, try surrounding the function declaration with parenthesis to hand-serialize it, e.g. `onSuccess: (function () {}).bind(this,...)`
Dereleased