How to parse variables to JSON Object (Javascript) - javascript

I want to be able to parse external variables into a JSON object.
Something like this would do:
var username = "zvincze";
And using that variable to parse a JSON object:
var json = '{"username":"VARIABLE_GOES_HERE"}'
var obj = JSON.parse(json);
This is a very simple question that I can't seem to figure out. In fact, I don't even know if there's a way to actually acheive something such as this.

You need to distinguish carefully between JSON and JavaScript objects. They are two entirely different things.
JSON is a language-independent character-based data representation that is used for data interchange. For instance, if you are sending data to a server, it needs to be in string form, so you would need to convert your data into JSON. If you are receiving data from a server, and it is JSON format, you need to convert it into a JavaScript object so you can use it in your JavaScript program.
JSON actually has nothing to do with JavaScript. For example, JSON could be used as a string-based data representation for Java programs exchanging data. Java and pretty much all other languages provide their own library routines for converting their native data into JSON and vice versa.
The only relationship between JSON and JavaScript objects used in JavaScript is that a JSON string looks much like a JavaScript object literal, with some additional restrictions, such as that keys must be quoted, that it cannot hold certain data types such as functions, and that it cannot hold circular references.
The "JS" part of "JSON" does not indicate that JSON is a basic JavaScript data structure, or that JSON is used in JavaScript for representing or manipulating data. It merely comes from the fact that, as mentioned above, the format of a JSON string is loosely modeled after that of a JavaScript object literal.
In normal day-to-day JavaScript programming, you will never use JSON, and don't need to worry about it. You will need to worry about JSON only when, as I said, you are sending data to somewhere, or receiving data from somewhere, that expects JSON as the data format. That is the case when making ajax calls, of course, but actually, even then, since jQuery's $.ajax will automatically convert data to and from JavaScript objects if you tell it the right types, even in that case you do not normally need to worry about JSON.
Note by the way that JSON can represent primitive values, not just JavaScript objects. For example, "1" is valid JSON which represents the number 1.
As I understand your question, you want to create a JavaScript object (not JSON) which contains as one of its values that of the variable username. You create a JavaScript object with regular old JavaScript object literal format, in this case
{username: username}
This means, create an object, with a single key named "username" (quote it if you please), whose value is that of the variable username. Again, unless you plan to send this object somewhere that expects a JSON string representation, there is no need to even think about JSON in this case.
In theory, yes, as one answer suggested, you could create a JSON string with the value of username "interpolated", using string arithmetic like '{"username":"' + VARIABLE_GOES_HERE + '"}', and then convert that JSON string into a JavaScript object using JSON.parse. However, there is absolutely no reason to jump through these hoops, when you can simply write the JavaScript object as a normal JavaScript object literal.
Another answer shows a way to define a regular JavaScript object, and then turn it into JSON using JSON.stringify. However, again, in your case, there is no need to do this unless you are planning to send the object somewhere.
Yet another answer shows a way to define a regular JavaScript object, then stringify it into a JSON string, then immediately parse it back into a JavaScript object, which will be exactly the same object you started with before stringifying and parsing. There's absolutely no need to do this.
One sees no small number of questions on SO trying to somehow manipulate or search or replace within JSON, using regexps for example. There are almost no cases where you need to even think of doing such a thing. JSON has two fundamental operations: converting values into JSON, and converting JSON into values. Both of those are built into the language in the form of JSON.stringify and JSON.parse, that do their jobs with absolute reliability and performance. If for some reason you need to modify data which is in JSON string format, don't manipulate the string; all you need to do is parse it into a JavaScript value, manipulate the value, and then convert it back into JSON.
Unfortunately, for unknown reasons, many JavaScript programmers who are learning the language, including many who have posted questions here on SO, have developed the misperception that JSON is a JavaScript object, or that they must think about JSON and stringifying and parsing in order to deal with plain old JavaScript objects, which is very much not the case.
Minor point, but you use the term "parse" in your question. I see more and more people using this word for some reason to mean "access" or "retrieve" or "extract". Actually, "parse" has a very specific meaning: to analyze a string-based representation of information (such as a program or data object), according to a particular grammar, into some suitable computer-friendly form for further processing. What JSON.parse does is parsing in this sense, because it is analyzing a string-based representation of information according to the JSON grammar into a JavaScript object for further processing.

You can simply concatenate strings like below...
var json = '{"username":"' + VARIABLE_GOES_HERE + '"}'
in your case:
var username = "zvincze";
var json = '{"username":"' + username + '"}';
Happy coding....

I think what you're doing is sort of odd. The object you create is json by definition (JavaScript Object Notation).
var obj = {};
obj.username = "zvincze";
//obj is now json
var str = JSON.stringify(obj);
//str == {'username':'zvincze'}
JSON.parse(obj) should fail since obj is already json.

Without messing with concatenation var json = '{"username":"'+ userName +'"}' you can:
var ob = {}; // or simply: var ob = {username:"zvincze"};
ob.surname = "Zvincze";
ob.name = "Zachary";
ob.id = "5182842";
var json = JSON.stringify(ob);
var obj = JSON.parse(json);
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

var json = JSON.stringify({username:"zvincze"})

Related

Rendering JSON string directly as Javascript object, vs. rendering string for JSON.parse

I have objects that I serialize into JSON strings on the server side for consumption by my JavaScript code. I then deliver these to the client along with the HTML content so that they are immediately available. I had been writing them into the response as strings that I then parse with JSON.parse, like this:
var json = "{ \"someKey\":\"someValue\" }"; // This string written in by server-side code
var parsed = JSON.parse(json);
Then it occurred to me that this is a waste of time, since I could just directly write the JSON string as a literal JavaScript object, like this:
var someObject = { "someKey" : "someValue" }; // This literal written in by server-side code
This saves the step of escaping the quotes in the string, followed by the step of parsing it back to an object.
I control the JSON rendering on the server side, and I never deliver strings that users have supplied. This seems like a no-brainer. But are there any gotchas to look out for -- any maximum sizes for JavaScript literal objects or anything like that?

JSON that contains functions

I have a website that returns a JSON-like data structure like this:
{
"name":"tom jones",
"no": 123,
"storedproc": function(){
callbuyer(0123);
}
}
I'm getting this data using $.ajax() with dataType "JSON". Unfortunately, my $.ajax() calls the error callback because my data contains a function().
How can I parse this correctly? I really need to store the function in a variable and call it later.
That is simply not legal JSON (as you know given the title of the question) See the offical JSON syntax. The nice thing about real JSON is that one can use JSON.parse which safely wraps an eval call.
While eval could be used, I would suggest revisiting the architecture of your application and find some other way to do what you are trying to do.
In particular, I would have the server return the 0123 only, and let your client keep the logic that lets it know, in certain cases, which functions apply (in the scenario here, the function would be callbuyer).
This should work because you say you want to call the function which is the value of the storedproc later. Since the body of this function contains a call to callbuyer it follows that your client side script knows what callbuyer is. The trick is for your server not to send back arbitrary, unconstrained functions, but rather data that your client can exploit somehow using the knowledge it has about the overall application.
Could you arrange to have the server return JSON like this:
{"name":"tom jones",
"no": 123,
"storeprocFn": callbuyer,
"arg": "0123"};
Then your callback function can call the callbuyer function and pass arg
Use eval to interpret the string as a javascript object. You won't be able to use the JSON data type though. I believe what you need to do is use 'text' as the dataType for the $.ajax call. Then do something like:
var data = eval('(' + text + ')');
Should work. Of course, eval is evil. But it would solve your problem. As long as you can guarantee there isn't anything malicious in the text (no unsanitized, user entered data) then you should be ok.
AFAIK, functions are left out when using JSON.stringify, it's just not meant to be used to clone full objects (props and methods). However, you might be able to pass the function body as a string.Say you decide on a string format like func=>var foo = 'bar'; return foo;. This should be passed as a regular JSON string, after parsing the object you could then iterate all properties, and convert those strings to functions like so:
for (var prop in parsedObj)
{
if (parsedObj.hasOwnProperty(prop) && parsedObj[prop].match(/^func\=\>/))
{
parsedObj[prop] = new Function(parsedObj[prop].replace('func=>',''));
}
}
Though, seriously, I'd say you might want to rethink your approach, this is not what JSON is for. It's unsafe, all JSON strings are eval'ed, after having made sure they contain no harmful code. This approach is creating a loophole/vulnerability that the JSON people worked hard for to seal off.
For your example will this work:
'user.storeproc = function() { callbuyer( user.no);};'
The Var 'user' is the object of the parsed json.
Ps: maybe you have to format user.no, from 123 to 0123
Following JSON extension, "JFON", does transport of functions and array-properties.
JFON uses eval and is intended for case if:
1) your data is from trusted source ( like not-derived from user input or is a code from your own server), and
2) you know there are no undesired side effects with context of "eval"
(it is a context of eval in function "fromJFON", line 127 )
3) it is costly to refactor your app to use "functionless" JSON;
4) JFON is one-day work, so may be needs more testing;
The idea: use selected property name to escape functions and arrays like
in strings when selected character "\" is used to pass \n and \ for itself.
In JFON, name "wrap" is selected to pass functions and itself: "wrap" : { "fun" : ... and "wrap" : { "esc" : ...
demo: http://landkey.org/Sandbox/z/spaceen86/js/btb/tests/jfon.htm
code ( use commit 0.0.86 ):
https://github.com/lancelab/spaceen/blob/master/js/btb/JFON.js
test: github.com/lancelab/spaceen/blob/master/js/btb/tests/jfon.htm
Here is another, "JWON" extension: JSON-comments, here-documents, monkey-patching of JSONs:
github.com/lancelab/Boardspirator/blob/master/diary/play/tp/jwon.js

Convert Javascript object to a JSON string

I want to directly convert a javascript object to string. I used following code.
var foo = {};
foo.test1 = test1;
foo.test2 = test2;
foo.test3 = test3;
var jsonObj = JSON.stringify(foo);
It works fine but it uses the json2 javascript library. However I need to do this in plain javascript without using any libraries. I know creating the json feed using passed parameters will work like this.
var jsonObj = "{\"test1\":\"" + test1+ "\",\"test2\":\"" + test2+ "\",\"test3\":\"" + test3+ "\"}";
However if the passed parameters(test1, test2 and test3) contains double quotes it will have issues.
What is the best approach to achieve this?
Thank you
You should escape the double quotes by performing a String.replace(/"/g, "\\\"") on each key and member. For this to work however, you need to guarantee that you will only have simple strings/ numbers in your JS object.
FYI, it should be noted that the json2 library will only be used when a native implementation of JSON does not exist; all modern browsers have JSON support build in (IE < 8 is the noticable exception).
I think you've totally misunderstood what JSON is. JSON Stands for Javascript Object Notation.
What you haven't realised is that foo is already an object and further have you actually thought about what you'd be coding to access jsonObj ?
Here's a hint jsonObj.test1 : looks familiar doesn't it.
What you might be trying to do is to create a string that looks like JSON content but isn't in fact an object. That's a different question though.
Hope this helps.

Convert json object to json string and use it's functions?

I have a json object with a function:
var thread = {
title: "my title",
delete: function() {
alert("deleted");
}
};
thread.delete(); // alerted "deleted"
thread_json = JSON.encode(thread); // convert to json from object
thread_object = JSON.decode(thread_json); // convert to object from json
thread_object.delete(); // this didn't work
After I converted it back from json string to object, I could not use delete() function.
When you convert something to json, the functions are gone?
Are there ways to keep them in the json string?
I'm using Mootools.
You got it. Take a look at that JSON.encode output. Only simple data types are allowed in JSON representations, partly for ease of creation, and partly for security. (The reason we use something like JSON.decode instead of eval is the possibility of embedding functions.)
You'll have to modify the JSON library source code to accept functions, or write your own in order to preserve the literal definition of the object upon conversion to string.
Consider, though, the possibility that you don't really need to do this. There's probably a better solution, but I can't begin to address that without knowing your exact situation.

How can I prevent auto-parsed, AJAX-gained JSON to become a window variable?

I'm using JSON to communicate some data through AJAX from the backend to the frontend (Javascript, of course). The XMLHttpRequest is done by a Prototypejs-written AJAX-handler (I'm still in the process of migrating to jQuery, but the noConflict-mode allows me to run both simultaneously), after which PHP sends the X-Json header with some data like objects = {'foo': 'bar'}.
The Prototypejs-Ajax.Request passes a json variable to the onSuccess-callback, containing all the JSONdata, so the processing isn't the hard part. However, I noticed that since the JSON is automatically evaluated, the objects variable is made global (and thus a member of the window object.
I know it's not really a problem since it's just an unused variable, but I always tried to stay away from global variables as much as possible. Additionally, the datasets may be pretty large on some occasions, so it'll just be a huge duplicate variable of which one is never used. So, if possible, I'd rather lose the global.
My question: how? If there's a good reason for this happening, or if this is just a Prototypejs-specific issue, or if this just indicates I'm doing something very wrong, please tell me :-)
Thanks!
Are you sending back objects = {"foo":"bar"} from PHP? When sending JSON, you just send {"foo":"bar"} and get the data as the return result of eval:
var json = '{"foo":"bar"}'; // This string would really be coming from PHP
// ...
var objects = eval('(' + json + ')'); // objects variable will be limited to the
// current scope.
If, for some reason, you must evaluate objects = ..., you can limit the variable to the current scope before running eval:
var objects;
eval('objects = {"foo":"bar"}');
Note that the PHP functions json_encode and json_decode will create "proper" JSON for you, which means it will use double quotes, and it will not use any kind of assignment (True JSON is limited to an array/object as the outer-most value, and it may not contain assignment or function calls. See the JSON specification.)
If the PHP is outputting objects = {'foo': 'bar'} then it isn't outputting JSON. JSON can't include the '=' character outside a string and uses the double quote character not the single quote. This means it is outputting JavaScript.
You have two options here.
The first is to try to restrict the scope of the JavaScript, the second is to fix the PHP so it outputs real JSON.
I would recommend the second option. Deal with JSON not JavaScript.
If you want to try to restrict it, then you need to limit the scope somehow. Possibly with:
function () {
eval("var " + php_generated_code);
doSomethingWith(object);
}
… although I'm not sure what the scope of eval() is.

Categories