I'm getting an odd error when using $.getJSON with node-async to a server running node/express with jsonp response.
I make two calls to the server using node-async iterating over an array but when all is done the second result has some properties which contain the values from the first.
The odd thing is that the server side response IS coming back - as one of the properties that came back is correct - but another property looks like it is overwritten on the second call by the property from the first.
On the server side, I've debugged it and checked the res.jsonp line which is returning the correct results, I've also checked it with some console logging server side.
Code below - TLDR results are as follows:
//Expecting results to be:
[
{"series":1, options:{serverSays:"Here is series 1"},data: [a:1,b:2,c:3]},
{"series":2, options:{serverSays:"Here is series 2"}, data: [x:9, y:8, z:7]}
]
//Actual Results are
[
{"series":1, options:{serverSays:"Here is series 1"}, data: [a:1,b:2,c:3]},
{"series":2, options:{serverSays:"Here is series 2"}, data: [a:1,b:2,c:3]}
]
Here's a simplified version of the code (with much junk taken out but logic remaining intact):
var series = [
{id: 1},
{id: 2}
]
var results = [];
//A function to get data from the server and return it
function getData(id, cb)
{
var url = serverUrl + "/GetSomeData/" + id;
$.getJSON(url)
.done(function (serverResponse)
{
console.log("Response from server: ", serverResponse)
cb({"series": id, options: serverResponse.options, data: serverResponse.data});
}
}
//A function to iterate through the series using async.forEach
function iterator(s, callback)
{
getData(s.id, function(data)
{
//Use the data
results.push(data);
//Tell async we are done with this iteration
callback()
});
}
function done(err)
{
console.log("Finished");
//Expecting results to be
//[
// {"series":1, options:{serverSays:"You Requested Series 1"},data: [a:1,b:2,c:3]},
// {"series":2, options:{serverSays:"You Requested Series 2"}, data: [x:9, y:8, z:7]}
//]
//Actual Results are
//[
// {"series":1, options:{serverSays:"You Requested Series 1"}, data: [a:1,b:2,c:3]},
// {"series":2, options:{serverSays:"You Requested Series 2"}, data: [a:1,b:2,c:3]}
//]
}
async.eachSeries(series, iterator, done);
I've tried it with async series, async parallel and with the promise style getJSON and the callback style getJSON - all show the same error.
Could be my client side code or else maybe I'm doing something silly with the server side jsonp.
Server side, I build the data then go
return res.jsonp(output);
Any thoughts?
Doh. Looks like I was being caught out by an external function call breaking the chrome inspector horribly!!
I finally realised that the chrome console was not displaying valid data in the inspector, but if i JSON.stringify'd the object it displayed correctly.
E.g.
console.log("Server response is: ", serverResponse) //In the getJSON callback
Would give the tree view for the incorrect object which would look like this:
{"series":2, options:{serverSays:"Here is series 2"}, data: [a:1,b:2,c:3]} //Incorrect data property
But doing
console.log("Server response is: ", JSON.stringify(serverResponse))
Showed the correct JSON:
{"series":2, options:{serverSays:"Here is series 2"}, data: [x:9, y:8, z:7]} //Correct data property
--
The cause? What I was doing with the data. One of the "junk taken out" lines that i removed from the example was a call to a highcharts chart to set the series data - along the lines of
getData(s.id, function(data)
{
//THE OMITTED LINE
chart.series[someSeries].setData(data.data);
//Tell async to add data to the result list
// and continue with the next iteration.
callback(null, data); // err = null
});
This was tripping over a bug I had in the chart definition, but instead of failing gracefully it somehow broke the chrome inspector...!
I'm guessing with the scope hell of node-async + $.getJSON + multiple functions + callbacks, this was the final straw. Go Figure!