views:

58

answers:

3

I have two files, one containing an array in PHP that is echoed via json_encode, and the other full of javascript functions for a webpage. One such function, that looks like this (and is unfinished):

/*
 * Function: selectVictim
 * Called from function laserOn()
 *
 * Selects a random victim from a list of victims
 *
 * @return String: victim
 */
function selectVictim()
{
var params = "url=queenofsheep.com/Sheep/victims.php";
var request = new ajaxRequest();

request.open("POST", "victims.php", true);
request.setRequestHeader("Content-Type",
                             "application/x-www-form-urlencoded");
request.setRequestHeader("Content-Length", params.length);
request.setRequestHeader("Connection", "close");

request.onreadystatechange = function ()
{
    if (this.readyState == 4)
    {
        if (this.status == 200)
        {
            if (this.responseText != null )
            {
                var vicString = this.responseText;
                var vicArray = eval('"'+vicString+'"');
                //var vicArray = vicString.split(',');
                //var numVic = Math.floor(Math.random() * (vicArray - 1));
                alert(vicArray);
            }
            else alert("Ajax error: No data received");
        }
        else alert("Ajax Error: " + this.statusText);
    }
}

request.send(params);
}

Is supposed to take in the array from the other file and do things to it that are beyond the scope of this question. Unfortunately, while this.responseText contains a JSON encoded array of the format

var jsonArr = 
     ["1","2,","3"]

activating the function does nothing, and evaling this.responseText yields "undefined."

What am I doing wrong here? I can provide more examples of the real code, the actual array, whatever, if need be. This is driving me crazy.

+1  A: 

Use request instead of this. this refers to the window object.

Edit: if var jsonArr=[1, 2, 3]; is literally the response, you should use eval(vicString+';jsonArr'); if you can't alter the response text.

If you'd run 'eval("var test=[1,2,3];")', you'ld have seen that it indeed returns undefined. But this isn't a good practice in using JSON.

Lekensteyn
Not necessarily. It depends on how the handler is called. You can set the value of `this` if you use `fn.apply()` or `fn.call()`. For example `fn.call("something")` sets `this` to the string `"something"`.
Vivin Paliath
Considering that it alerts, I'm assuming that `this` refers to the request object (otherwise it would never have passed the `if` statements unless window has both `readyState` and `status`)...
ircmaxell
In this case `this` refers to `window`. I didn't say it always does.
Lekensteyn
@ircmaxell, he didn't say it's put in those if statements.
Lekensteyn
@Lekensteyn. Again, not necessarily :). `request.onreadystatechange.call("something");`. I just set `this` to `"something"`. Without seeing how `ajaxRequest` is implemented, and how the handler is called, there is no way to tell.
Vivin Paliath
I think Lekensteyn's solution is correct. I'm voting this up.
Vivin Paliath
What do you mean that he didn't say it's put in those if statements? Look at the code given. When `onreadystatechange` is called, it does a bunch of checks against `this.readyState`, `this.status` and `this.responseText`... Unless `window` has those properties all set (and to valid values), I can't see how the alert could be tripped without `this` being bound to `request`...?
ircmaxell
Whoops, missed "*evaling* this.responseText yields undefined. See updated answer.
Lekensteyn
+1  A: 

Try adding "(" and ")" to the Eval Function. That's how I've seen it done in the past

var myObject = eval('(' + vicString + ')');
Dutchie432
A: 

Set the content type of the response in the server to "application/json" and you won't have to use eval anymore.
Also you would be better of using an ajax framework instead of using your own ajax functions.

lodge