Reputation: 117
I have an array of arrays of strings saved in a database column as a varchar:
[["ben"],["john","mike"],["ben"]]
I want to parse the data back into an array of arrays, so I can show the data on the screen. While attempting to do this, I ran into an awkward and annoying problem:
Here's the JSON response that is generated on the server and sent back to the client:
var response = "[{\"Names\":\""+ rows[i].Names + "\"}]";
res.send(response);
Here's the client code I wrote to parse the data:
jQuery.ajax({
type: "GET",
url: ...,
dataType: 'json',
contentType: "application/json; charset=utf-8"
}).done(function(data) {
jQuery.each(JSON.parse(data), function(i, parsedData) {
var names = JSON.parse(parsedData.Names);
var labels = "";
for (var n = 0; n < names.length; n++) {
var label = "<label>" + names[n] + "</label>";
labels = labels + label;
}
console.log(labels);
});
});
This is the error i'm getting:
Here's the JSON validation:
How can I solve this?
Upvotes: 0
Views: 64
Reputation: 338148
There is a simple rule:
Never use string tools to create or modify JSON. No string concatenation (+
), no string replace and God forbid no regex.
The only way to produce JSON is to use a JSON serializer on a data structure. And the only way to manipulate JSON is to parse it, modify the data structure, and then serialize it again. JSON itself is to be treated as a constant, for all intents and purposes.
Your server code violates that rule. Change it like this:
var responseData = [{
Names: rows[i].Names
}];
var response = JSON.stringify(responseData);
In the above, responseData
is a data structure. You are free to modify it. response
is derived from that. You are not free to modify it, the only thing you can do with response
is to write it to the client.
Note that rows[i].Names
might be JSON itself, so you end up with a double-encoded value in your response.
Provided the server sends the Content-Type: application/json
header, the client can use this:
jQuery.get("...").done(function(data) {
// data is already parsed here, you don't need to parse it
jQuery.each(data, function(i, item) {
// item.Names is not yet (!) parsed here, so we need to parse it
var names = JSON.parse(item.Names);
var labels = names.map(function (name) {
return $("<label>", {text: name});
}
console.log( labels );
});
});
If you don't want to call JSON.parse()
on the client, you have to call it on the server:
var responseData = [{
Names: JSON.parse(rows[i].Names)
}];
var response = JSON.stringify(responseData);
Upvotes: 3