ErvingGoffman ErvingGoffman - 1 year ago 134
Javascript Question

JSON.parse don't convert a string to an object

Why I can't to convert a string (JSON format) to an object?

This is js function that receives a JSON formatted string from server:

function GetData(){
xhr = new XMLHttpRequest;
xhr.open('GET', 'http://'+ ip + ":" + port + "/api/s", true);

xhr.onreadystatechange = function () {
if (xhr.status == 200 && xhr.readyState == 4) {

try {
var data = JSON.parse(xhr.responseText);
for (var i=0; i<data['result'].length; i++) {
...some operations here...
}
}

catch(e) {
console.log(e.message + " in " + xhr.responseText);
return}
}
}
xhr.send();
}


But I get string, JSON.parse not work:

Cannot read property 'length' of undefined in "{\"result\":[{\"id\":1, \"region\":\"\u0420\u0435\u0441\u043f\u0443\u0431\u043b\u0438\u043a\u0430 \u0410\u0434\u044b\u0433\u0435\u044f\"}, {\"id\":2, \"region\":\"\u0420\u0435\u0441\u043f\u0443\u0431\u043b\u0438\u043a\u0430 \u0411\u0430\u0448\u043a\u043e\u0440\u0442\u043e\u0441\u0442\u0430\u043d\"}, {\"id\":3, \"region\" ... and so on ...


I can't get length of JSON-object property value, can't to access to it's property 'result' and so on.

But why?

Answer Source

You expect xhr.responseText to contain a JSON encoded object. It looks like it actually contains a JSON encoded string (and that the JSON encoded string contains a JSON encoded object). Note the " characters around xhr.responseText when you console.log it.

That is to say: You have an object which has been encoded as JSON which has then been encoded as JSON again.

When you run JSON.parse(xhr.responseText), you decode the first layer of JSON encoding. This gives you a string of JSON that represents an object.

That string doesn't have a result property.

You need to decode the second set to JSON to get your object:

var json = JSON.parse(xhr.responseText);
var data = JSON.parse(json);
console.log(data.result.length);

console.log("Compare single encoded data:");
var json_obj = "{ \"result\": [] }";
console.log("JSON Object: " + json_obj);
var obj = JSON.parse(json_obj);
console.log("Object result length", obj.result.length);
console.log("-------------");
console.log("With double encoded data:");
var json_str = "\"{ \\\"result\\\": [] }\"";
console.log("JSON String (See the extra quotes?): " + json_str);
var json_obj_2 = JSON.parse(json_str);
console.log("JSON Object 2: " + json_obj_2);
var obj_2 = JSON.parse(json_obj_2);
console.log("Object 2 result length", obj.result.length);


A better solution would be to figure out why the data was being double encoded in the first place and not do that.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download