HI guys,
I seem to be having an issue declaring a json string.
The original string I have is this:

var jsonString = '{ "details" : [' +
    '{"text":"Lorem ipsum dolor sit amet, consectetur  0", "firstName":"Jack0", "surname":"Dee0", "moreInfo":"This is extra information"},' +
    '{"text":"Lorem ipsum dolor sit amet, consectetur  1", "firstName":"Jack1", "surname":"Dee1", "moreInfo":"This is extra information"},' +

and if I parse it

jsonStringParsed = JSON.parse(jsonString);

I get what I expected in the console, two objects:

            moreInfo:"This is extra information"
            text:"Lorem ipsum dolor sit amet, consectetur  0"

            moreInfo:"This is extra information"
            text:"Lorem ipsum dolor sit amet, consectetur  1"

The problem is that after I parse it and loop through the objects in jsonStringParsed I don't want to have to use the syntax jsonString.details.xxxx, but I want direct access to the object, something like this instead jsonString.xxxx(the reason doesn't matter too much at this stage as this is part of a much larger application) so I decided to change the declaration of the json string to this:

var jsonString = 
    '{"text":"Lorem ipsum dolor sit amet, consectetur  0", "firstName":"Jack0", "surname":"Dee0", "moreInfo":"This is extra information"},' +
    '{"text":"Lorem ipsum dolor sit amet, consectetur  1", "firstName":"Jack1", "surname":"Dee1", "moreInfo":"This is extra information"}';

But this doesn't work, and I don't quite understand why as nowehere - not that I could find it at least - said that a json string can't be declared like that, quite the contrary in fact. Does anybody have any idea why it doesn't work?
The error I get is:

Uncaught SyntaxError: Unexpected token , in JSON at position 132
    at JSON.parse (<anonymous>)
    at script.js:13

and the position 132 points directly to the comma in here

This is extra information"},{"text":"Lorem ipsum dolor sit amet
Member Avatar

You are creating multiple objects separated by commas. If you have surrounding [] you make an array of objects.

Ah wait, you mean something like this then:

var jsonString = '[' +
        '{"text":"Lorem ipsum dolor sit amet, consectetur  0", "firstName":"Jack0", "surname":"Dee0", "moreInfo":"This is extra information"},' +
        '{"text":"Lorem ipsum dolor sit amet, consectetur  1", "firstName":"Jack1", "surname":"Dee1", "moreInfo":"This is extra information"}' +

But I thought that the specification said that a json string has to start with a { and not with a [, in fact the first version of the string starts with a curly brace.
So if I start with a [, is there any implication? what I mean is that this json string will be sent to the application from somewhere not yet specified, I'll parse it, store the results in a variable, loop through the literal objects and create an object for each line. Then I'll do some data manipulation, change the properties of the object, stringify the back into a json string and send it back

Member Avatar

You can send multiple objects separately as separate variables or as an array or possibly as an object of objects. As primarily a php programmer I consider js objects in this context to be more like associated arrays than traditional objects with properties and methods.

Member Avatar

AFAIK, strictly, you are correct with regard to the enclosing {}. However, you are passing a "json string" not the json itself. So decoding the string should be straightforward, with or without the enclosing {}.

If you are creating an object, it will pretty much need a "label" for the contained objects, like "details". The list of objects also need an array to contain them.



Seems the correct structure to me. If you don't like the "details" in your variable name...

var data = jsonString.details;
var firstItemText = data[0]['text'];

the problem with the label is that I have to include it when accessing the objects, and i don't want that, I want direct access to the objects, that's why I was thinking to remove the label altogether. The reasons for that is that, when the json string is created - because it's created outside the application - I can't guarantee that the label is 'details' or whatever else, so I thought it'd be tricky to access the objects when you're not sure what the label is. For now I have hardcoded it, but that's not a good solution as the author can call it anything. You suggested

var data = jsonString.details;
var firstItemText = data[0]['text'];

but there is still the label in there, so I need to replace that jsonString.details find a way to get that 'details' programmatically and not hardcode it, but, alas, I couldn't find any. Is there any way to return just the label?

Member Avatar

The problem with creating a js object is that they rely on "labels" as js objects are not numerically-indexed arrays - they require some sort of "label" to determine their properties (or methods). The "label" for general content like yours is useful as it can be converted to XML easily and the top level "label" (or property) is then the top level tag.

Anyhow, after further digging, I came across this: http://stackoverflow.com/questions/19623339/is-a-list-array-valid-json

It suggests that json may start as an object OR an array. It mentions why an object with property could be preferrable. So seems we were both wrong - you don't HAVE TO start with {}.

Interesting. So technically I don't have to have the label in it, that's good. Still I don't really know whether when they produce the json string they will or not include the label. They are likely to export their data as a json string so I don't know whether the export will include a label or not, and I have no idea if there is a way to find out unfortunately or a way to control that, like to force it to include or not a label.
In any case I've just found a way to access the actual label of the json object so that I don't have to hardcoded it every time I want to access the object. Apparently I need to use this:
console.log("label: " + Object.keys(jsonStringParsed)[0]);
and that gives me 'details'.
I found this here just for reference: http://stackoverflow.com/questions/22565077/javascript-get-json-key-name

Member Avatar

If you don't have an idea of what the json string structure, you'll need to test for object vs array and then something like the snippet you posted. However, you may have levels upon levels with multiple properties - how do you know which property holds the data you need?

yes that's a good point, I think I have a rough idea of how the structure is going to look like but I can't be 100% sure. As mentioned I don't have direct control over the json string generated, but only indirect, so I'd imagine we would then decide on some kind of standard, otherwise, as you said, how would I even know how to access the data in it?!

Actually that Object.keys(jsonStringParsed)[0] isn't so good after all, because it returns the label as a string, which means that I can't use it in this fashion as I thought I would:
jsonString.Object.keys(jsonStringParsed)[0].xxxx, as it says that the keys is undefined...

EDIT: OK, I figured that out, strange syntax for me, it will now be jsonString[Object.keys(jsonStringParsed)[0]].xxxx

commented: Great - you saved me a post :) +15