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.
Related
I was getting list in array form. So at first place i converted array list to string-
var myJsonString = JSON.stringify(result);
myJsonString="[{"productId":"PI_NAME",
"firstName":null,
"lastName":null,
"customer":null
},
{"productId":"PI_NAME",
"firstName":null,
"lastName":null,
"customer":null
}]"
But again i need to convert myJsonString to Json format, What i need to do? I mean i need to replace 1st" and last ", I guess
You need to call parse now.
JSON.parse(myJsonString)
First, if you ever find yourself building a JSON string by concatenating strings, know that this is probably the wrong approach.
I don't really understand how the first line of your code relates to the second, in that you are not doing anything with JSON-encoded string output from result, but instead just overwriting this on the following line.
So, I am going to limit my answer to show how you could better form JSON from an object/array definition like you have. That might look like this:
// build data structure first
// in this example we are using javascript array and object literal notation.
var objArray = [
{
"productId":"PI_NAME",
"firstName":null,
"lastName":null,
"customer":null
},{
"productId":"PI_NAME",
"firstName":null,
"lastName":null,
"customer":null
}
];
// now that your data structure is built, encoded it to JSON
var JsonString = JSON.stringify(objArray);
Now if you want to work with JSON-encoded data, You just do the opposite:
var newObjArray = JSON.parse(JsonString);
These are really the only two commands you should ever use in javascript when encoding/decoding JSON. You should not try to manually build or modify JSON strings, unless you have a very specific reason to do so.
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.
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).
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.
I want to convert below string to an array in javascript.
{a:12, b:c, foo:bar}
How do I convert this string into array of objects? Any cool idea?
I think that the best way of doing this, as Douglas Crockford (one of the biggests gurus of JavaScript) suggests in here is using the JSON native parser, as it is not only faster than the eval(), it's also more secure.
Native JSON parser is already available in:
Firefox 3.5+
IE 8+
Opera 10.5+
Safari Safari 4.0.3+
Chrome (don't know which version)
And Crockford has made a safe fallback in javascript, called json2.js, which is an adaption of the eval() approach, with some security bits added and with the native JSON parsers API. You just need to include that file, remove its first line, and use the native JSON parser, and if it's not present json2 would do the work.
Here is an example:
var myJSONString = '{ "a": 1, "b": 2 }',
myObject = JSON.parse(myJSONString);
Once parsed you'll get an object with attributes a and b, and as you may know, you can treat an object as a hash table or associative array in JavaScript, so you would be able to access the values like this:
myObject['a'];
If you just want a simple array and not an associative one you could do something like:
var myArray = [];
for(var i in myObject) {
myArray.push(myObject[i]);
}
Lastly, although not necessary in plain JavaScript, the JSON spec requires double quoting the key of the members. So the navite parser won't work without it. If I were you I would add it, but if it is not possible use the var myObject = eval( "(" + myString + ")" ); approach.
Since your string is malformed JSON, a JSON parser can't parse it properly and even eval() will throw an error. It's also not an Array but a HashMap or simply an Object literal (malformed). If the Object literal will only contain number and string values (and no child objects/arrays) you can use the following code.
function malformedJSON2Array (tar) {
var arr = [];
tar = tar.replace(/^\{|\}$/g,'').split(',');
for(var i=0,cur,pair;cur=tar[i];i++){
arr[i] = {};
pair = cur.split(':');
arr[i][pair[0]] = /^\d*$/.test(pair[1]) ? +pair[1] : pair[1];
}
return arr;
}
malformedJSON2Array("{a:12, b:c, foo:bar}");
// result -> [{a:12},{b:'c'},{foo:'bar'}]
That code will turn your string into an Array of Objects (plural).
If however you actually wanted a HashMap (Associative Array) and NOT an array, use the following code:
function malformedJSON2Object(tar) {
var obj = {};
tar = tar.replace(/^\{|\}$/g,'').split(',');
for(var i=0,cur,pair;cur=tar[i];i++){
pair = cur.split(':');
obj[pair[0]] = /^\d*$/.test(pair[1]) ? +pair[1] : pair[1];
}
return obj;
}
malformedJSON2Object("{a:12, b:c, foo:bar}");
// result -> {a:12,b:'c',foo:'bar'}
The above code will become a lot more complex when you start nesting objects and arrays. Basically you'd have to rewrite JSON.js and JSON2.js to support malformed JSON.
Also consider the following option, which is still bad I admit, but marginally better then sticking JSON inside an HTML tag's attribute.
<div id="DATA001">bla</div>
<!-- namespacing your data is even better! -->
<script>var DATA001 = {a:12,b:"c",foo:"bar"};</script>
I am assuming you omit quote marks in the string because you had put it inside an HTML tag's attribute and didn't want to escape quotes.
The simplest, but unsafe way to do it is:
eval('(' + myJSONtext + ')')
But since this will interpret any javascript code, it has security holes. To protect against this use a json parser. If you're using a framework (jquery, mootools, etc.) there's a framework-specific call. Most of them are based on Douglas Crawford's parser available at http://www.json.org/js.html.
You can use "for in"
var myObject = {a:'12', b:'c', foo:'bar'};
var myArray = [];
for(key in myObject) {
var value = myObject[key];
myArray[key] = value;
}
myArray['a']; // returns 12
Notes: considering that myObject only have one level of key-value pairs.
JSON.parse will do the trick. Once parsed, you can push them into the array.
var object = JSON.parse(param);
var array = [];
for(var i in object) {
array.push(object[i]);
}
If you're using jQuery, there's the $.parseJSON() function. It throws an exception if the string is malformed, and "Additionally if you pass in nothing, an empty string, null, or undefined, 'null' will be returned from parseJSON. Where the browser provides a native implementation of JSON.parse, jQuery uses it to parse the string"
Use safe evaluation. Unlike JSON.parse, this doesn't require the keys or values to be quoted. Quote values only if they contain embedded commas.
const myStr = "{a:1, b:2, c:3}";
const myObj = string_exp(myStr);
console.log("dot: " + myObj.c);
function string_exp(sCmd) {
return Function(`'use strict'; return (${sCmd})`)();
}
https://dev.to/spukas/everything-wrong-with-javascript-eval-35on#:~:text=the%20variable%20exists.-,Alternatives,-The%20most%20simple