Converting JavaScript JSON data to Python JSON - javascript

I have JavaScript JSON data:
var data = '{a: 10, b: 20}'
I want to convert it to Python JSON. How can I do?
My situation:
I have script that read text from a website. website has data in javascript variables like I show in example. I extracted variable part '{a: 10, b: 20}'. But for the python, it is still string format. I need to convert that data into Python JSON so I can do further work.
How can I convert JavaScript JSON to Python JSON?

Python JSON is a bit of a misnomer as JSON (as in JavaScript Object Notation) is a subset of JavaScript and simply describes a JavaScript object. It is an exchange format that does not depend on the language you are using it with.
You can use the json module to parse JSON in Python, and return an equivalent Python object.

it need regex replace before can convert it json
import re
import json
data = '''{a: 10, b: true, c :"string", "d" : jsVariable, e:'single'}'''
# replace single with double quote
data = data.replace("'", '"')
# wrap key with double quotes
data = re.sub(r"(\w+)\s?:", r'"\1":', data)
# wrap value with double quotes
# but not for interger or boolean
data = re.sub(r":\s?(?!(\d+|true|false))(\w+)", r':"\2"', data)
data = json.loads(data)
print(data['a']) # 10
print(json.dumps(data, indent=2)) # formatted json string

Apparently some libraries like RSON can help you.
According to that answer

var data = '{a: 10, b: 20}' is not a valid JSON. It is valid JavaScript
If you were to do
var data = JSON.stringify({ a: 10, b: 20 });
you would find it actually becomes
var data = '{ "a": 10, "b": 20 }'
The extra " around the a and b variables being the part that makes this valid JSON. The confusion comes from the fact that JavaScript is more forgiving than JSON.
Don't feel bad. You will not be the only one who will fall into this trap.

Related

Large JSON String not parsing using JSON.parse or angular.fromJson

I'm trying to replace the angularjs POST query with standalone JSON response string.
When angular GET / POST queries returns a response automatically converted to JSON and the code was working like charm.
Now, I'm trying to have the json response stored as a javascript string variable in the controller and then trying to parse it using JSON.stringify() and subsequently using JSON.parse().
There is no error but the resulting json object's member variables can't be accessed using the . operator
var staticData = '{"someKey":"someValue", "masterJobs":[]}'; //very large json string.
var resultString = JSON.stringify(staticData);
$scope.staticTestData = JSON.parse(resultString);
console.log($scope.staticTestData.masterJobs); // this displays 'undefined'
Controller function with the large JSON is available here.
You already have a string, so there is no need to use JSON.stringify.
Just use the following code:
var staticData = '{"someKey":"someValue", "masterJobs":[]}'; //very large json string.
$scope.staticTestData = JSON.parse(staticData);
console.log($scope.staticTestData.masterJobs);

How is JSON related to serialization?

What is serialization?
Serialization is the process of converting the object into stream of bytes to send it over a network or store it in a file in such a way that the object can be reconstructed again.
What is JSON?
JSON is the data interchange format, having a fixed structure. When de-serialized it return the Javascript object.
I did some Googling but can't find the how they are related? They are often mentioned together. I need to know what is going on under the hood when we say that we need to serialize the data in JSON.
JSON is basically structured text.
One example would be a client-server architecture, such as web browser - server communication is. The data from the server can be serialized from native format to JSON (text) and transferred through the network (stream of bytes) to the client (web browser). When the data gets to the client (web browser), it is deserialized to a Javascript object and handled (maybe something is displayed to the user or the UI manipulated - non-essential).
A Java example
Let's say we've a simple class in our server application, which is written in Java:
class Person {
String name;
int age;
}
and we've an instance of this class:
Person person = new Person();
person.name = "John";
person.age = 32;
We've chosen to use JSON as the data format in server-to-client communications. Converting our instance of a person to JSON looks like this:
String json = "{\"person\": {\"name\": \"John\", \"age\": 32} }";
Now we just write this String to HTTP response, from where the client reads it - to a string. The string is then deserialized to a Javascript object. Deserialization could look like this (more about JSON.parse at MDN / JSON.parse):
/* We get responseText by AJAX and it looks exactly the same that we sent from our web
server - IT IS TEXT, the variable 'json' contents in our Java application. */
var responseText = "..."
var data = JSON.parse( responseText ); // JSON.parse is supported by modern browsers
Data looks something like this if written directly as a Javascript object:
data = {
person: {
name: john,
age: 32
}
};
So, we started in the server side from a Java-object. We serialized the Java-object to a JSON-string and sent it through the network to the client. The client deserialized the JSON-string to a Javascript-object (which can be properly dealt with in language-specific way).
JSON is a format that allows you to represent your objects as a string / text, which can then be stored, sent etc.
Another example would be XML, which is also often used for serialization.
Example:
Object
var Person = new Object();
Person.FirstName = "Foo";
Person.LastName = "Foo";
Person.Age = 24;
JSON example serialization
{
Person:
{
FirstName: "Foo",
LastName: "Bar",
Age: 42
}
}
XML example serialization
<Person>
<FirstName>Foo</FirstName>
<LastName>Bar</LastName>
<Age>42</Age>
</Person>
Since you asked "what is going on under the hood": Simply explained, the serialization algorithm would iterate all properties of the object and store their names and values in a string of the requested format (JSON, XML, ...)
JSON represent collections of key/value pairs. JSON Parsers (like JSON.parse, json_decode) will map this representation to an appropriate data structure that reflects these collections. JSON Serializers (like JSON.stringify, json_encode) do the inverse, they take a data structure and map it to JSON.
For example in PHP:
$obj['a'] = 'b'; //Associative Array
$obj['c'] = 'd';
Its JSON representation would be:
'{
"a" : "b",
"c" : "d"
}'
Keys and values of the respective data structure (in this case an associative array).
In Javascript:
var obj = {
a : 'b',
c : 'd'
}
This is a Javascript object, when serialized it maps to the same JSON:
'{
"a" : "b",
"c" : "d"
}'
JSON describes a precise string format, which is why I've marked my JSON in between ' '. A string representation of your data structures can be very useful for many things, like sending them as a message.

How to solve the dilemma while handle JSON in Neo4j Cypher?

I've found that I can't use the standard JSON string in the Cypher query while I were writing a Node.js application:
var neo4j = require('neo4j')
,db = new neo4j.GraphDatabase('http://localhost:7474')
,enc_datum = JSON.stringify({id: 1, data: 'foo'})
,qstr = ['MATCH (n %DATUM)'
,'RETURN n'
].join('\n')
.replace('%DATUM', enc_datum)
db.query(qstr)
It would complain about the '"' character, because Cypher accept encoded object like this:
MATCH (n {id: 1, data: 'foo'})
RETURN n
Which is not what encoded with JSON:
var enc_datum = JSON.stringify({id: 1, data: 'foo'})
console.log(enc_datum)
// would be {"id":1,"data":"foo"}
The error messages show that Cypher, or the Neo4j module, doesn't accpet standard JSON because of the " character. It would complain that the next character after the { should be identifier or something else.
So I got stuck: either I must handle the JSON string with some nasty RegExpr before it got embedded in the query string, or I must invent a way to encode objects just for the tiny " character. I just want to ask if there're some more suitable solutions before I jump into these two tricky ways...
(I now solve this in test by using eval instead of JSON to eval my encoded data, while the string would be directly used in the Cypher query so I can't use JSON to stringify it. But I can't handle client encoded JSON in this way)
MATCH (n {id: 1, data: 'foo'})
The format you seem to be using is JSON5. You can avoid double quotes with code like this:
var jju = require('jju')
jju.stringify({id: 1, data: 'foo'}, {quote:"'"}).replace(/"/g,'\\x22')
// result: "{id: 1, data: 'foo'}" (string)
jju.parse("{id: 1, data: 'foo'}")
// result: {id: 1, data: 'foo'} (object)
Please note two important things here:
"quote" parameter ensures that module will always use single quotes to wrap strings
replace() ensures that all double quotes will be encoded as \x22 if they happen to be in your input (i.e. data: 'foo"bar')
I don't know what other restrictions do that database have, maybe it's worth to encode it with base64 or something.
Cypher doesn't use JSON it is a map format that looks a bit like JSON but doesn't use quotes for keys
use parameters instead MATCH (n {props}) pass the actual parameters as values
like this
{"query","MATCH (n {props}) return n",
"params": {"props":{"id":1,"data":"foo"}}}

JSON.parse parsing JSON with nested objects

I'm attempting to parse a JSON string with nested objects received in the response of a post request. After running JSON.parse(responseText), the result is in the following format:
[{
"atco":"43000156407",
"location":{
"longitude":"-1.7876500000000000",
"latitude":"52.4147200000000000","
timestamp":"2013-03-19 11:30:00"
},
"name":"Solihull Station Interchange",
"road":"STATION APPROACH",
"direction":"NA",
"locality":"Solihull",
"town":"Solihull"}, ...
I thought I would then be able pull values out using the following as an example, but all I get is undefined.
var atco = json[0].atco;
I've also tried json[0][0] but that returns an individual character from the JSON ([) . Does this indicate the JSON hasn't parsed correctly, or is this expected behaviour and I'm just referencing incorrectly?
This means that your JSON is being double encoded. Make sure you only encode it once on the server.
As proof, after you've parsed it, parse it again.
var parsed = JSON.parse(resposneText);
var parsed2 = JSON.parse(parsed);
alert(parsed2.atco);
Either that, or you're parsing it but then trying to select the data from the original string. This would obviously not work.

How to send js array via ajax?

I can only send string or numeric values,how to send an array?
You'll probably get a slew of answers all saying "JSON".
Here are some case specific examples. 'data' holds what you send.
var numArray = [17, 42, 23];
data = '[' + numArray + ']';
var strArray = ['foo', 'bar', 'baz'];
data = '["' + numArray.join('", "') + '"]';
For the general case, use a function that recursively encodes objects to JSON. If you really want me to, I'll post an example implementation, but it's a fun project so you might want to give it a try. If you're using a Javascript library, it might have a JSON encoder of it's own (such as jQuery's serializeArray).
There's are no built-in JSON serializers in javascript so you will need to use a library. A good one is json2.js.
Here's a sample:
// suppose you have an array of some objects:
var array = [{ prop1: 'value1', prop2: 10 }, { prop1: 'value2', prop2: 20 }];
// convert it to json string:
var jsonString = JSON.stringify(array);
// TODO: send the jsonString variable as a parameter in an ajax request
// On the server side you will need a JSON deserializer
// to convert values back to an array of objects
I can only send string or numeric values
Actually you can only send strings. When you include a number it is just turned into a string; it's up to the server-side script to parse that back into a number if it wants to.
how to send an array?
The native HTML-forms way of sending multiple values is using multiple inputs. You can reproduce this by including the same named parameter multiple times. To send [1,2,3]:
http://www.example.com/ajax.script?a=1&a=2&a=3
The same multiple-parameter-instance query string can be sent in an AJAX post request.
If you are using a higher-level framework to create the form-encoded string, it depends on the framework how it accepts multiple parameter instances. For example with jQuery you can post an object like {a: [1,2,3]}.
The other way is to forget the standard HTML form encoding and just pass all your values in whatever special encoding you like that allows you to retain datatypes and structure. Usually this would be JavaScript value literals (JSON):
http://www.example.com/ajax.script?a=%5B1%2C2%2C3%D
(that is, [1,2,3], URL-encoded.) You then need a JSON parser on the server to recreate native array values there.
You can actually send Arrays in a much cleaner way instead of trying to encoding JSON.
For example, this works
$.post("yourapp.php", { 'data[]': ["iphone", "galaxy"] });
See http://api.jquery.com/jQuery.post/ for more.

Categories