tags:

views:

930

answers:

3

Hi,

I'm trying to iterate in a JSON object that is returned from a PHP script. The return part is something like:

$json = array("result" => -1, 
    "errors" => array(
    "error1" => array("name" => "email","value" => "err1"),
    "error2" => array("name" => "pass","value" => "err2")
        )
        ); 

$encoded = json_encode($json);
echo $encoded;

So, in JavaScript I can do:

var resp = eval('(' + transport.responseText + ')');
alert(resp.length);
alert(resp.errors.error1.name);

But I can't do:

alert(resp.errors.length);

I would like to iterate errors, that's why I'm trying to get the length. Can somebody give me a hint? Thanks!

+1  A: 

Have a look at your JSON output. resp.errors will be something like this:

{"error1": {"name": "email", "value": "err1"}, ...}

As you can see, it's an object, not an array (since you passed it an associative array and not an numerically indexed array.) If you want to loop through an object in JavaScript, you do it like this:

for (var error in resp.errors) {
    alert(resp.errors[error].name);
}

If you want it to be a JavaScript array, your PHP should look like this:

$json = array("result" => -1, "errors" => array(
    array("name" => "email","value" => "err1"),
    array("name" => "email","value" => "err1")
));
Blixt
+2  A: 

To be able to do that, you need resp.errors to be a Javascript array, and not a Javascript object.

In PHP, arrays can have named-keys ; that is not possible in Javascript ; so, when using json_encode, the errors PHP array is "translated" to a JS object : your JSON data looks like this :

{"result":-1,"errors":{"error1":{"name":"email","value":"err1"},"error2":{"name":"pass","value":"err2"}}}

Instead, you would want it to look like this :

{"result":-1,"errors":[{"name":"email","value":"err1"},{"name":"pass","value":"err2"}]}

Notice that "errors" in an array, without named-keys.

To achieve that, your PHP code would need to be :

$json = array(
    "result" => -1, 
    "errors" => array(
            array("name" => "email","value" => "err1"),
            array("name" => "pass","value" => "err2")
        )
    ); 
$encoded = json_encode($json);
echo $encoded;

(Just remove the named-keys on errors)

Pascal MARTIN
You can use a for in loop to iterate object properties.
jason
Agreed ; but if you want to work with an array, why not use an array ? (and, that way, you won't have to use hasOwnProperty or the like)
Pascal MARTIN
A: 

If you inspect the evaluated object in Firebug, you would see that "errors" is not an array but an object(associated arrays in PHP translates to object in JS). So you need to use for-in statement to iterate through an object.

You need to check every property name with hasOwnProperty to be sure that it is something you have sent, not some prototype property.

BYK