1

"This" is what I retrieve from a server:

enter image description here

after an ajax call in jQuery:

$.ajax({
    type: "POST",
    url: URL + "/webservices/WS.asmx/MyFunction",
    data: JSON.stringify({ "ID": ID }),
    contentType: 'application/json; charset=utf-8',
    success: function (json) {

    },
    error: function (jqxhr, text, error) {

    }
});

and I want to iterate the items inside data (which is an array). Tried with:

for (i in json.data) {
    var feed = json.data[i];
    console.log(feed.message);
}

but it prints nothing. Where am I wrong?

markzzz
  • 47,390
  • 120
  • 299
  • 507
  • you want to parse the response before that using `json=JSON.parse(json);` – Sherin Jose Feb 20 '14 at 11:17
  • but it is already a JSON :O – markzzz Feb 20 '14 at 11:17
  • but in ajax it will appear as a string only, otherwise you must provide the `dataType:"json"` – Sherin Jose Feb 20 '14 at 11:18
  • Unrelated to your question, but: using `for-in` to loop through array indexes without safeguards is usually a bad idea. Reasons why and how to do it properly in [this answer](http://stackoverflow.com/questions/9329446/for-each-in-an-array-how-to-do-that-in-javascript/9329476#9329476). – T.J. Crowder Feb 20 '14 at 11:47

4 Answers4

2

If what you've shown is really what you're getting in your success method, you have an object with a property, d, which contains a JSON string. You can parse it like this:

success: function(response) {
    var data = $.parseJSON(response.d).data;
    // use the data, which is an array
}

From your comment below:

But why I need to use $.parseJSON? Can't just manage it with the request? dataType for example, but still not works.

You don't need dataType, it would appear the server is returning a correct MIME type and so jQuery is already handling the first level of parsing (deserialization) correctly.

Whatever is sending you the data appears to be sending it double-encoded: First it encodes the array, then creates an object and assigns the array to it as a data property, serializes that object to JSON, then puts that string on a d property of another object, and serializes that. So although jQuery is automatically handling the first parsing (deserializing) step for you, it doesn't know about the need for the second one. I suspect you can fix this at the server level; you might want to post a separate question asking how to do that.


From your further comment:

It retuns from a .NET webservice method. I download the JSON from Facebook, after a call. And I store it inside a json variable. Then I just return it as string. I think webservice serialize that already serialized json, right?

Ah, so that's what's going wrong. You have three options:

  1. Keep doing what you're doing and do the explicit $.parseJSON call above.

  2. Do whatever you need to do in your web method to tell it that you're going to send back raw JSON and it shouldn't encode it; in that case, jQuery will have already parsed it for you by the time you receive it in success and you can drop the parseJSON call.

  3. Parse the string you get from Facebook, then put the resulting array in the structure that your web method returns. Then (again) jQuery will parse it for you and you can use response.d.data directly without further parsing.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • This seems to works. But why I need to use $.parseJSON? Can't just manage it with the request? dataType for example, but still not works. – markzzz Feb 20 '14 at 11:23
  • It retuns from a .NET webservice method. I download the JSON from Facebook, after a call. And I store it inside a json variable. Then I just return it as string. I think webservice serialize that already serialized json, right? – markzzz Feb 20 '14 at 11:31
  • http://stackoverflow.com/questions/21906607/implicit-conversion-to-json-in-a-webservice-method – markzzz Feb 20 '14 at 11:36
  • @markzzz: I've updated the answer to address these comments. Good luck with your other question, I'm afraid I haven't used that tech so I can't help you update your web method. I'm sure someone will, though. – T.J. Crowder Feb 20 '14 at 11:39
  • Seems that nobody know of to disable it in a .NET webservice, damn! – markzzz Feb 20 '14 at 13:39
0

As @T.J.Crowder has pointed out your problem is related to the way you serialize your data on your backend, which is not a good practice to send the json as a string, in a real json object.

you should do it like:

success: function (json) {
    var jsonObject = JSON.parse(json.d);
    //then iterate through it
    for(var i=0;i<jsonObject.data.length;i++){
        var feed = jsonObject.data[i];
        console.log(feed);
    }
},

The point is using for(var key in jsonObject.data), is not safe in JavaScript, because additional prototype properties would show up in your keys.

Mehran Hatami
  • 12,723
  • 6
  • 28
  • 35
  • The screenshot clearly shows us that what the success method is receiving is not just a string. – T.J. Crowder Feb 20 '14 at 11:22
  • @WaqarAlamgir: `contentType` doesn't relate to what the server sends *back* (that's `dataType`; and yes, these names were poorly-chosen as you'd expect a `dataType` option to relate to a `data` option, wouldn't you?). `contentType` tells the server that what the OP is sending *it* (the `data` option) is JSON (which it is). – T.J. Crowder Feb 20 '14 at 11:27
  • @T.J. Crowder in that case you don't need to call JSON.parse – Waqar Alamgir Feb 20 '14 at 11:29
  • @WaqarAlamgir: There's nothing in my comment above that says `JSON.parse` isn't needed. Recommend reading the question, my answer, and the comments on it carefully. – T.J. Crowder Feb 20 '14 at 11:30
  • @T.J. Crowder I was referring to the answer not your comment! – Waqar Alamgir Feb 20 '14 at 11:32
  • @WaqarAlamgir: Ah. Yes, as I commented to Mehran above, this answer is wrong for the information in the question. – T.J. Crowder Feb 20 '14 at 11:34
-1

I assume json is an object not string and already converted to json object. Also used json.d.data not json.data

use var in for loop and print feed not feed.message:

for (var i in json.d.data) {
    var feed = json.d.data[i];
    console.log(feed);
}

because I can not see {feed:{message:''}} there

Waqar Alamgir
  • 9,828
  • 4
  • 30
  • 36
-1

Try using

for (var i in json.d.data) {
    var feed = json.d.data[i];
    console.log(i+" "+feed);
}

where i = Key & feed = value

vaibhav silar
  • 2,905
  • 2
  • 15
  • 18