How does JSON.parse() work? - javascript

I have not worked too much on javascript. And, I need to parse a JSON string. So, I want to know what exactly JSON.parse does. For example :
If I assign a json string to a variable like this,
var ab = {"name":"abcd", "details":{"address":"pqrst", "Phone":1234567890}};
Now when I print 'ab', I get an object.
Similarly when I do this :
var pq = '{"name":"abcd", "details":{"address":"pqrst", "Phone":1234567890}}';
var rs = JSON.parse(pq);
The 'rs' is the same object as 'ab'. So what is the difference in two approaches and what does JSON.parse did differently ?
This might be a silly question. But it would be helpful if anybody can explain this.
Thanks.

A Javascript object is a data type in Javascript - it's have property and value pair as you define in your first example.
var ab = {"name":"abcd", "details":{"address":"pqrst", "Phone":1234567890}};
Now What is Json : A JSON string is a data interchange format - it is nothing more than a bunch of characters formatted a particular way (in order for different programs to communicate with each other)
var pq = '{"name":"abcd", "details":{"address":"pqrst", "Phone":1234567890}}';
so it's is a String With json Format.
and at last JSON.parse() Returns the Object corresponding to the given JSON text.

Here is my explanation with a jsfiddle.
//this is already a valid javascript object
//no need for you to use JSON.parse()
var obj1 = {"name":"abcd", "details":"1234"};
console.log(obj1);
//assume you want to pass a json* in your code with an ajax request
//you will receive a string formatted like a javascript object
var str1 = '{"name":"abcd", "details":"1234"}';
console.log(str1);
//in your code you probably want to treat it as an object
//so in order to do so you will use JSON.parse(), which will
//parse the string into a javascript object
var obj2 = JSON.parse(str1);
console.log(obj2);
JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML.

Your 'ab' variable isn't a string, it is a proper javascript object, since you used the {} around it. If you encased the whole thing in "" then it would be a string and would print out as a single line.

Data Type!! That is the answer.
In this case, ab is an object while pq is a string (vaguely speaking). Print is just an operation that displays 'anything' as a string. However, you have to look at the two differently.
String itself is an object which has properties and methods associated with it. In this case, pq is like an object which has a value: {"name":"abcd", "details":{"address":"pqrst", "Phone":1234567890}} and for example, it has a property called length whose value is 66.
But ab is an object and you can look at name and details as its properties.
What JSON.parse() did differently was that, it parsed (converted) that string into an object. Not all strings can be parsed into objects. Try passing {"name":"abc" and JSON.parse will throw an exception.
Before parsing, pq did not have any property name. If you did something like pq.name, it'll return you undefined. But when you parsed it using JSON.parse() then rs.name will return the string "abcd". But rs will not have the property length anymore because it is not a string. If you tried rs.length then you'll get a value undefined.

Related

Access specific part of JSON JS

I am trying to access the t part of the "data": object below. I am doing this by doing console.log(message.data.f) however this returns undefined. I do not understand why I cannot access it in this way. See object below:
"data":"{\"e\":\"53845\",\"f\":\"SCORE\",\"pf\":[{\"p\":\"HOME\",\"v\":\"0\"},{\"p\":\"AWAY\",\"v\":\"0\"}],\"^t\":\"f\",\"i\":\"357575\",\"z\":1492771602631}",
Note I have marked the part of the object I wish to access with a ^
Your data property is a JSON string and probably all the object is a JSON string.
You need to parse the string as JSON
var obj = JSON.parse(myObj.data);
and then you can access:
console.log(obj.f);
If your first object, the one containing data, is not already a JSON too and its name is for example myFirstObject you need to do just this:
var jsonObj = JSON.parse(myFirstObject);
console.log(jsonObj.f);
Your message is nothing but string. Parse it first to a corresponding object to access its variables.
var parsed = JSON.parse(message);
console.log(message.data.t);

Do I have to parse a JSON string and then traverse the resulting object or can I just traverse the string?

I'm learning Google Maps API; a call to its geolocation API returns a giant JSON string (sample: https://maps.googleapis.com/maps/api/geocode/json?address=66+Fort+Washington+Avenue+New+Yor,NY&key=AIzaSyAGLzbjA0rEl5whQgiuZZdIGVzPZzLv9Kg). If I'm looking for a particular key/value pair out of that resulting set of data to use in my Java script application, is it better to convert that JSON string into an object (parse) and then traverse that object for that key/value pair, or is it Ok just to traverse the returned JSON string itself? What are the pros/cons of each?
Parsing the JSON will always result in easier to read code and is less sensitive to changes in the data that you are receiving. However, if you are looking at pure performance it depends on how unique the data is that you are searching for in the returned JSON string, and how many searches you are doing. If you (for instance) just wanted the lat/long location from the returned string you mentioned above then you could do this:
var index = string.search("location");
var index2 = string.substring(index).search(/-?\d/); // finds first number
lat = parseFloat(string.substring(index+index2));
var index3 = string.substring(index+index2).search("lng");
var index4 = string.substring(index+index2+index3).search(/-?\d/); // finds first number
lon = parseFloat(string.substring(index+index2+index3+index4));
Or, by parsing it you could do this:
var obj = JSON.parse(string);
lat = obj.results[0].geometry.bounds.northeast.lat;
lon = obj.results[0].geometry.bounds.northeast.lon;
Clearly the parsed version is easier to read. However, I ran this 200000 times each, and found that the string search based approach was slightly more than 4 times faster than the JSON object parsing approach. There may have been other ways to optimize the search based approach but you get the idea.
You should use JSON.parse to turn your string into a JavaScript object before attempting to access its properties. You cannot "traverse the returned JSON string itself":
var json = '{ "property": "value" }'
// JSON strings cannot be traversed
console.log(typeof json) //=> "string"
console.log(json.property) //=> undefined
var object = JSON.parse(json)
// Objects can be traversed
console.log(typeof object) //=> "object"
console.log(object.property) //=> "value"
If the api is returning json inside an string, you could parse it and just go throught the elements till you find what you need. Otherwise how would you traverse the string? From my point of view, that's something you shouldn't do.

convert string to dynamic array with variables in javascript

How would I take a string (that I got from a page using jQuery's text()) such as:
var myData = "[{name:'xxx',data:[1,2,3,4,5]},{name:'yyy',data:[5,4,3,2,1]}]"; //this is a string :(
And turn it into the actual javascript object that I need, so for example:
var myObject = [{name:'xxx',data:[1,2,3,4,5]},{name:'yyy',data:[5,4,3,2,1]}];
So 'name' and 'data' will be non-dynamic variables, however names value, the data array and the length of myObject will be dynamic.
Not really sure where to start with this one. I am guessing that I will have to do a whole lot of spliting and looping, but I am open to suggestions.
Well, it can be done very easily:
var myObject = eval(myData);
However, you should be aware of the risks of the eval function. As it runs the value as a Javascript expression, it would also run any harmful code that would be in the string, so you should only use it when you have full control over what's in the string.
If you could change the format to be JSON, you could safely parse it without risks of code injection:
var myData = '[{"name":"xxx","data":[1,2,3,4,5]},{"name":"yyy","data":[5,4,3,2,1]}]';
var myObject = $.parseJSON(myData);
You mean,
var myObject = eval('(' + myData + ')');
?
EDIT
Its major con is that you can put any javascript code (not only JSON) to eval (Chrome's F12 lets anyone to exploit this). AS you are using jQuery, best choice will be
var myObject = $.parseJSON(myData);
for cross browser compatibility.
$.parseJSON
Takes a well-formed JSON string and returns the resulting JavaScript
object. Passing in a malformed JSON string may result in an exception
being thrown. For example, the following are all malformed JSON
strings:
{test: 1} (test does not have double quotes around it).
{'test': 1} ('test' is using single quotes instead of double quotes).

Javascript JSON.parse or directly access

When we can read a property directly from string:
var data = {"id":1,"name":"abc","address":{"streetName":"cde","streetId":2}};
console.log(data.address.streetName); // cde
Why do people use JSON.parse:
var obj = JSON.parse(data);
console.log(obj.address.streetName); // cde
It is not a string, but Javascript object. String is given below
var data = '{"id":1,"name":"abc","address":{"streetName":"cde","streetId":2}}';
to make it object we use JSON.parse
var obj = JSON.parse(data);
console.log(obj.address.streetName); // cde
In your first example, data is an object, but in your second example, data is a JSON string.
That's a major difference. You could call eval(data) to parse a JSON string, but that's very unsafe.
JSON.parse() expects a string. More specifically, a string with a JSON-encoded piece of data.
If it's applied to an object then it's an error, the source of which is probably the common confusion that seems to exist between JavaScript objects and the JSON format.

Problem parsing JSON

I encounter problems tring to consume a third party web servive in JSON format. The JSON response from the server kinda looks like this:
{
"ID":10079,
"DateTime":new Date(1288384200000),
"TimeZoneID":"W. Europe Standard Time",
"groupID":284,
"groupOrderID":10
}
I use JavaScript with no additional libs to parse the JSON.
//Parse JSON string to JS Object
var messageAsJSObj = JSON.parse(fullResultJSON);
The parsing fails. A JSON validatior tells me, "new Date(1288384200000)" is not valid.
Is there a library which could help me parse the JSON string?
Like others have pointed out, it's invalid JSON. One solution is to use eval() instead of JSON.parse() but that leaves you with a potential security issue instead.
A better approach might be to search for and replace these offending issues, turning the data into valid JSON:
fullResultJSON = fullResultJSON.replace(/new Date\((\d+)\)/g, '$1');
You can even go one step further and "revive" these fields into JavaScript Date objects using the second argument for JSON.parse():
var messageAsJSObj = JSON.parse(fullResultJSON, function (key, value) {
if (key == "DateTime")
return new Date(value);
return value;
});
Here's an example: http://jsfiddle.net/AndyE/vcXnE/
Your example is not valid JSON, since JSON is a data exchange technology. You can turn your example into a Javascript object using eval:
var almostJSON = "{
"ID":10079,
"DateTime":new Date(1288384200000),
"TimeZoneID":"W. Europe Standard Time",
"groupID":284,
"groupOrderID":10,
}";
and then evaling it:
var myObject = eval('(' + almostJSON + ')');
Then, myObject should hold what you're looking for.
Note that functions are not allowed in JSON because that could compromise security.
try var obj = eval('(' + fullResultJSON + ')'); and you'll have the object like Pekka said. Don't forget to use the extra '()' though. And indeed json should have both property and value enclosed in quotes.
Parsing fails because all you can parse in a json object are null, strings, numbers, objects, arrays and boolean values so new Date(1288384200000), cannot be parsed
You have also another problem, last property shouldn't have the trailing comma.

Categories

Resources