laker02
laker02

Reputation: 117

Parsing string of array of array of string back to array

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:

enter image description here

Here's the JSON validation:

enter image description here

How can I solve this?

Upvotes: 0

Views: 64

Answers (1)

Tomalak
Tomalak

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

Related Questions