How to correctly parse the JSON? - javascript

I have developed a Cordova android plugin for my library. The library is used for sending events across different connected devices.
JS interface receives a JSON from the java side. What I want to do is to parse this before reaching the application so that the developer can directly use it as a JS object. When I tried to parse the JSON in my plugin's JS interface, I am running into issues. Below is an example:
Received by JS interface:
{"key":"name","data":"{\"name\":\"neil\",\"age\":2,\"address\":\"2 Hill St\"}"}
After parsing in JS interface:
Object {key: "name", data: "{"name":"neil","age":2,"address":"2 Hill St"}"}
data:"{"name":"neil","age":2,"address":"2 Hill St"}"
key:"name"
__proto__:Object
As you can see, if this data reaches the app and the developer accesses the data:
eventData.key = name;
eventData.data = {"name":"neil","age":2,"address":"2 Hill St"};
eventData.data.name = undefined
How can I parse the inner data as well in my JS interface so that the developer can access directly. In the above case, he has to parse eventData.data to access the properties. I don't want this to happen and I want to do this in JS interface itself.
Please note that eventData can have many properties and hence they should be properly parsed before passing into the app.
I am new to Javascript and hence finding it difficult to understand the problem.

It seems that your returned JSON contains a string for the data property.
var response = {"key":"name","data":"{\"name\":\"neil\",\"age\":2,\"address\":\"2 Hill St\"}"};
//Parse the data
var jsonData = JSON.parse(response.data);
console.log(jsonData.name); //neil
console.log(jsonData.age); //2
console.log(jsonData.address);//"2 Hill St"

As others pointed out, you have to do JSON.parse(eventData.data) as the data comes as a string.
You have to look why that happens. The inner data might be stored in this way, in some cases its valid to store it in db as flat object or it is stringified twice by mistake:
var innerdata = JSON.stringify({ name: "neil" });
var eventData = JSON.stringify({ key: "name", data: innerdata });
would correspond to your received string.
Correct way to stringify in first place would be:
var innerdata = { name: "neil" };
var eventData = JSON.stringify({ key: "name", data: innerdata });

Related

How to send javascript object literals from a Node backend to the browser frontend?

I am using Node where I have JavaScript object literals with methods in the backend, e.g.:
const report = {
id: 1,
title: 'Quarterly Report for Department 12345',
abstract: 'This report shows the results of the sales and marketing divisions.',
searchText: function () {
return this.title + '|' + this.abstract;
}
};
And I want to send these object literals to the frontend via AJAX and be able to call the methods on these objects as I can in the backend.
But even though I can send the objects to the frontend without JSON.stringify(), they are still converted to plain JSON by the time they reach my frontend:
Am I missing something, or is there not a way to send full object literals from backend to frontend. I'm using Axios.
But even though I can send the objects to the frontend without JSON.stringify(),
It sounds like you are using JSON.stringify … just indirectly (via a library).
JSON has no function data type. So you can't just use JSON.
You have a few options.
Listed in the order I'd recommend them in.
Resolve the methods
In your example, your function simple return this.title + '|' + this.abstract; so you could replace it with a string:
const report = {
id: 1,
title: 'Quarterly Report for Department 12345',
abstract: 'This report shows the results of the sales and marketing divisions.',
searchText: 'Quarterly Report for Department 12345|This report shows the results of the sales and marketing divisions.'
}
};
You could use the replacer argument of JSON.stringify to do this automatically for any method on the object.
This is the simplest option but results in data that doesn't update dynamically so it might not be suitable for your needs.
Add the methods with client-side code
Send a simple object which doesn't have the method but does have a field which describes the type of object it does.
Then inflate it on the client:
const type = ajaxResponse.type;
const Constructor = collectionOfConstructorFunctions[type];
const data = new Constructor(ajaxResponse.data);
Send JavaScript instead
You could use JSONP instead of Axios.
The response would be application/javascript instead of application/json so you could encode function expressions in the returned data.
I don't recommend this option.
Encode the functions in the JSON and then include them client-side
This is horrible.
const report = {
id: 1,
title: 'Quarterly Report for Department 12345',
abstract: 'This report shows the results of the sales and marketing divisions.',
searchText: "return this.title + '|' + this.abstract;"
}
and then, on the client:
report.searchText = new Function(report.searchText);
console.log(report.searchText());
This is effectively using eval. Don't do it.

Save/Load Variables in js

I'm trying to create a save/load function for my game in js, but I have basically no idea with how to go through with doing this. I can save variables to a JSON file or LocalStorage, but I don't know how to load them back into the program. I'm also pretty sure I'm exporting variables the wrong way as well. Any help?
Normally, I use JSON format to store and read data (of any type).
To save data (using key gamedata as example):
var myData = {
name: 'David',
score: 10
}
localStorage.setItem('gamedata', JSON.stringify(myData));
** without JSON.stringify, you data will be saved as string [Object object]
To retrieve the data back:
var savedData = localStorage.getItem('gamedata'); // savedData is string
var myData = JSON.parse(savedData); // parse JSON string to java object
setup a bin on www.myJSON.com. p5 has built in functionality for ajax requests such as loadJSON. that way it's not in local storage and you can access your data if you have it on github. I know your struggle, I used to deal with this sort of issue myself before I found myJSON

In node.js how to extract uid from returned facebook providerData json array?

I've got my users signing in with facebook and that gets stored in firebase auth. In index.js i've got an onCreate function that stores some facebook related data in firestore.
When i log to cloud functions console event.data.providerData I get this:
[ { displayName: 'xxxx xxxxx',
photoURL: 'https://scontent.xx.fbcdn.net/v/t1.0-1/p100x100/xxxxxxxxx_439xxx336xxxxxx.jpg?oh=bcxxxxxxxxxxx431ce&oe=xxxx4xxx3',
providerId: 'facebook.com',
uid: 'xxxxx725xxxxxx80' } ]
In my index.js file i've set this as
const providerData = event.data.providerData;
This always confuses me and i've read about it a lot.
These are my questions:
Is this a javascript object? Or a JSON object? Or a JSON array?
Does this need to be parsed? eg. JSON.parse(event.data.providerData)? What is JSON.parse actually doing?
To get access to the uid I have tried:
providerData[3]
providerData.uid
providerData["uid"]
providerData['uid']
JSON.parse(providerData) - and then all the above again
var obj = JSON.parse(providerData);
console.log( obj.uid );
I know there are plenty of posts out there re: similar topics and I think i've read a lot of them.
Thanks.
It's an array containing a JSON object at index 0.
The javascript interpreter is automatically parsing Valid JSON as a Javascript object.
Knowing that, you can now access directly the properties of your object like this:
providerData[0].displayName
providerData[0].photoURL
providerData[0].providerId
providerData[0].uid // <-- Your use case

object has no method push in node js

I am trying to append the user details from the registration form to the json file so that the user-details can be used for authentication. the problem is i am not able append to the json file in correct format.The code i have tried so far is,
var filename= "./user_login.json";
var contents = fs.readFileSync(filename);
var jsonContent = JSON.parse(contents);
//sample data
var data =[
{
"try" : "till success"
}
];
jsonContent.push(data);
fs.writeFileSync(filename,jsonContent);
I have tried different methods that i found by googling and nothing worked so far. I want the data to be stored in correct format. Most of the times i got this error like object has no push function. So what is the alternative to that?
The correct format i am looking for is ,
[
user1-details : {
//user1 details
},
user2-deatils : {
}//So on
]
Object has no push function, arrays do. Your json is invalid too, it should be an array:
[ // here
{
//user1 details
},
{
//So on
}
] // and here
Now, you can use push(). However, data is an array, if you want an array of objects in your json file, it should be a simple object:
var data = {
"try" : "till success"
};
You also have to stringify the object before writing it back to the file:
fs.writeFileSync(filename, JSON.stringify(jsonContent));
You should consider using something like node-json-db, it will take care of reading/writing the file(s) and it gives you helper functions (save(), push()...).

Serialize MVC model to JSON

I am trying to do a very simple task: get an MVC model, and send it back to server as JSON. I tried
#Html.Raw(Json.Encode(Model));
When debugging the JS, I see that the date objects on the serialized JSON look like: /date (00064321)/ and when passing the serialized JSON to the server, the dates are null on the server-side. Anyone understand what is going on?
Instead of JSON encoding the model directly you have to create an anonymous object converting the date-time properties to strings.
Ex.
var meeting = new Meeting
{
Name = "Project Updates",
StartDateTime = DateTime.Now
};
Passing directly the model..
#Html.Raw(Json.Encode(meeting))
produces
{"Name":"Project Updates","StartDateTime":"\/Date(1338381576306)\/"}
and
#Html.Raw(Json.Encode(new {
Name = meeting.Name,
StartDateTime = meeting.StartDateTime.ToString()
}))
produces
{"Name":"Project Updates","StartDateTime":"5/30/2012 6:09:36 PM"}
as expected.

Categories

Resources