Unable to extract json response - json

I am trying to extract a JSON response.When I try to access the object within the json array it returns undefined
weather= [{"id":711,"main":"Smoke","description":"smoke","icon":"50d"}]
var x=JSON.stringify(weather)
x[0].main= returns =>undefined

You can simply use Array#map OR Array#forEach function to get all you JSON data. You do not need to use JSON.stringify in your response.
Demo:
let weather = [{
"id": 711,
"main": "Smoke",
"description": "smoke",
"icon": "50d"
}]
weather.map(function(x) {
console.log(x.id) //711
console.log(x.main) //Smoke
console.log(x.description) //smoke
console.log(x.icon) //50d
})

I'm not sure what you're trying to accomplish or what you've tried, but here is how that works:
const weather = [{"id":711,"main":"Smoke","description":"smoke","icon":"50d"}]
document.querySelector('#id').textContent = weather[0].id
document.querySelector('#json').textContent = JSON.stringify(weather)
ID:
<div id="id"></div>
Stringified JSON:
<div id="json"></div>
To access an element of an array you can reference an index or loop through it:
const myArray = [1, 2, 3];
myArray[0] // 1
myArray[1] // 2
myArray[2] // 3
for (let i = 0 ; i < myArray.length ; i++) {
console.log(myArray[i]);
}
To access a property of an object you can either use dot notation or the key name as the index:
const myObject = {'a': 1, 'b': 2}
myObject.a // 1
myObject['b'] // 2
JSON.stringify converts your JSON into a string. This is useful for sending it over a connection to a host that may or may not recognize JSON.

Related

Add item to JSON array using JsonPatchDocument

I am trying to add an element to a JSON array using Microsoft's JsonPatch implementation in .NET 6:
JSON input:
{ "foo": [ 1 ] }
Expected JSON output:
{ "foo": [ 1, 2 ] }
Following their documentation, I ended up with the following code:
string input = #"{ ""foo"": [ 1 ] }";
dynamic obj = JsonSerializer.Deserialize<ExpandoObject>(input);
var patch = new JsonPatchDocument();
patch.Add("/foo/-", 2);
string output = JsonSerializer.Serialize(obj);
Console.WriteLine(output); // throws JsonPatchException, expected { "foo": [ 1, 2 ] }
I expect the foo property of my object to contain an array equal to [1, 2], but instead it fails with the following error:
Microsoft.AspNetCore.JsonPatch.Exceptions.JsonPatchException: The target location specified by path segment '-' was not found.
A Replace operation on the foo property successfully updates the ExpandoObject, but the Add operation fails. Am I missing something obvious?
I also tried using JsonNode instead of ExpandoObject to no avail (JsonNode obj = JsonSerializer.Deserialize<JsonNode>(input);). The code throws the same error.
In the meantime, as a workaround, I am using JsonPatch.Net. The code looks similar:
string input = #"{ ""foo"": [ 1 ] }";
JsonNode obj = JsonSerializer.Deserialize<JsonNode>(input);
var patch = new JsonPatch(PatchOperation.Add(JsonPointer.Parse("/foo/-"), 2));
PatchResult patchResult = patch.Apply(obj);
string output = JsonSerializer.Serialize(patchResult.Result);
Console.WriteLine(output); // { "foo": [ 1, 2 ] }

Parsing JSON error cannot read property 'url' of undefined

I have been trying to parse JSON, which have 3 different set of data where one element have various number of children and sometimes none. I am getting an error when there is no children present or only one present. I declared the JSON as var data.
JSON A
{
"floorplan": [
{
"title": "plan1",
"url": "https://media.plan1.pdf"
},
{
"title": "plan2",
"url": "https://media.plan2.pdf"
}
]
}
JSON B
{"floorplan": []}
JSON C
{
"floorplan": [
{
"title": "plan1",
"url": "https://media.plan1.pdf"
}
]
}
I parsed the JSON like this:
var items = JSON.parse(data);
return {
floorplan1: items.floorplan[0].url;
floorplan2: items.floorplan[1].url;
}
But, it only returned data for the JSON A, for other 2 it gave TypeError: Cannot read property 'url' of undefined.
I modified the code to check if floorplan have at least one child and then parse data.
var items = JSON.parse(data);
var plan = items.floorplan[0];
if(plan){
return {
floorplan1: items.floorplan[0].url;
floorplan2: items.floorplan[1].url;
}
}
The new code returned data for JSON A and B(as empty row), but gave error for C. C have one child still it got the error.
I also tried this code, still got the error for JSON C.
var items = JSON.parse(data);
var plan = items.floorplan[0];
var plan1;
var plan2;
if(plan){
plan1 = items.floorplan[0].url;
plan2 = items.floorplan[1].url;
}
return{
floorplan1 : plan1 ? plan1 : null;
floorplan2 : plan2 ? plan2 : null;
}
Is there any method I can try to get data returned for all 3 types of JSON?
let data = `
[{"floorplan": [{
"title": "plan1",
"url": "https://media.plan1.pdf"
}, {
"title": "plan2",
"url": "https://media.plan2.pdf"
}]},
{"floorplan": []},
{"floorplan": [{
"title": "plan1",
"url": "https://media.plan1.pdf"
}]}]`;
let json = JSON.parse(data);
//console.log(json);
json.forEach(items=>{
//console.log(items);
let o = {
floorplan1: items.floorplan.length > 0 ? items.floorplan[0].url : '',
floorplan2: items.floorplan.length > 1 ? items.floorplan[1].url : ''
};
console.log(o);
o = {
floorplan1: (items.floorplan[0] || {'url':''}).url,
floorplan2: (items.floorplan[1] || {'url':''}).url
};
console.log(o);
o = {
floorplan1: items.floorplan[0]?.url,
floorplan2: items.floorplan[1]?.url
};
console.log(o);
const {floorplan: [one = {url:''}, two = {url:''}]} = items;
o = {
floorplan1: one.url,
floorplan2: two.url
};
console.log(o);
});
Sure. A few ways, and more than I have here. I have put all the raw data into one string, parsed it into json and then iterated through that. In each loop my variable items will correspond to one of the json variables you created and referenced in your question as items.
In the first example, I check to make sure that items.floorplan has at least enough elements to contain the url I'm trying to reference, then use the ternary operator ? to output that URL if it exists or an empty string if it doesn't.
In the second example, I use the || (OR) operator to return the first object that evaluates to true. If items.floorplan[x] exists, then it will be that node, and if it doesn't I provide a default object with an empty url property on the right hand side, and then just use the url from the resulting object.
In the third, I use the optional chaining operator that was introduced in 2020. This method will return undefined if the url doesn't exist.
In the fourth example, I use destructuring to pull values out of the items variable, and make sure that there is a default value for url in case the items variable doesn't have a corresponding value.
But there are many more ways to go about it. These are just a few, and you can't necessarily say which approach is better. It's dependent on your intent and environment. With the exception of optional chaining (which shows undefined if the property doesn't exist), you can see these produce the same results.
DOCS for optional chaining: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
DOCS for destructuring: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
An article on destructuring: https://javascript.info/destructuring-assignment

Restructuring a large amount of values in a JSON file

I have a JSON file with a large amount of the following values:
"values": [
"Foo": 1,
"Bar": 2,
"Baz": 3,
...
],
How do I efficiently convert this into:
"values": [
{
"name": "Foo",
"value": 1
},
{
"name": "Bar",
"value": 2
},
{
"name": "Baz",
"value": 3
},
...
],
Any help would be appreciated!
Okay, so there are two problems with your input. The first is the fact that the given JSON is invalid, so can't directly be parsed. The square brackets after "values" should be curly brackets, to allow for a hash instead of an array:
let raw_old_data =
// Read the old file
fs.readFileSync('./input_data.json').toString()
// Remove all newlines which could interfere with the regex
.replace(/[\r\n]/g, '')
// Replace the square brackets after `"values"` with curly braces
.replace(/"values": \[(.+?)\]/g, '"values": { $1 }');
To convert this (now valid) string to a JSON object, you use JSON.parse:
let old_data = JSON.parse(raw_old_data);
The second problem is that the format in which the values are stored doesn't match your needs. You want to convert from { key: "value" } to [ name: "key", value: "value" ]. The following function can do that, assuming your version of Node supports ES6 (If not, look at Murillo's answer):
function fix_format(obj) {
// This is where we keep the new items in the correct format
let res = [];
// Loop over all values
Object.keys(obj.values).forEach(name => {
let value = obj.values[name];
// Change the format and add to resulting array
res.push({
// If the variable is the same as the key of the hash, it doesn't have to be specified
name,
value,
});
});
return res;
}
All that's then left to do is loop all data from the old object through that function with the Array.map function:
let new_data = old_data.map(fix_format);
And optionally write it back to a file to use with a different program:
fs.writeFileSync('./formatted_data.json', JSON.stringify(data, null, 2));
Note: The 2 in the JSON.stringify function indicates that the resulting JSON should be padded with 2 spaces, to keep it readable.
With ES6:
Object.keys(values).map(name => ({
name,
value: values[name]
}))
Without ES6:
var keys = Object.keys(values);
var newValues = [];
for(var i = 0; i < keys.length; i++){
newValues.push({
name: keys[i],
value: values[keys[i]]
})
}
If your intention is to use the received data i.e obtain data from DB (e.g MSSql, MySql...) using the connection.query(your_custom_sql_query, (err, rows, fields)
for more info:Node.js MySQL Select From Table
I'll recommend you to use:
const myJson = JSON.stringify(rows[0]);

Confused on int conversion

I'm writing a node js program that does the below.
get the json.
parse it.
print to console.
Currently I'm able to do the above three things very smoothly. But my problem comes up here. I'm trying to convert a value from json to int. and below is my sample data.
{
"Items": [
{
"accountId": "12345",
"pin": "1234",
"userId": "user1",
"dueDate": "5/20/2017",
"_id": "2",
"dueAmount": "4000",
"totalBalance": "10000"
}
],
"Count": 1,
"ScannedCount": 4
}
and from the above json I'll need the dueAmount in int format so I tried the below code.
var userDueDate = JSON.stringify(res.Items[0].dueDate);
var userDueAmount = JSON.stringify(res.Items[0].dueAmount);
var userTotalBalance = JSON.stringify(res.Items[0].totalBalance);
var intUsingNumber = Number(userDueAmount);
var intUsingParseInt = parseInt(userDueAmount);
console.log('by using Number : ' + intUsingNumber + ' and the type is :' + (typeof intUsingNumber));
console.log('by using Parse : ' + intUsingParseInt + ' and the type is :' + (typeof intUsingParseInt));
and when I run this program I get the output as
by using Number : NaN and the type is :number
by using Parse : NaN and the type is :number
Where in I need to print 4000 instead of NaN.
Also, what I'm confused is, the type is showing it as a number, but the value is given as NaN.
Please let me know where am I going wrong and how can I fix it.
Thanks
JSON is a JS object wrapped as a string:
let json = "{"dueAmount":"4000"}" - is a JSON object,
let jsObj = {"dueAmount":"4000"} is not.
If you receive a JSON object, you need to convert it to JS object by
let result = JSON.parse(json)
and then
parseInt(result.dueAmount)
Try below code (Don't need to use JSON.stringify)
var userDueDate =res.Items[0].dueDate;
var userDueAmount = res.Items[0].dueAmount;
var userTotalBalance = res.Items[0].totalBalance;
var intUsingParseInt = parseInt(userDueAmount);
console.log('by using Parse : ' + intUsingParseInt + ' and the type is :' + (typeof intUsingParseInt));
Assuming that res is a JSON object. You can simply use parseInt function to get number format.
var am = parseInt(res.Items[0].dueAmount)
You should not use JSON.stringify here. Cause it converts a JSON object to a String.

How can i list the values of a Node in JSON ?

Say, I have a JSON that has an array of "Topics"
I need to list all "created_at" values of all the topics
without the other data , using the Chrome console
P.S : I'm Using JSONView
You can loop through the objects in your array and simply access the property created_at.
Example
var json = {
all_topics: [{
"created_at:" "2016-08-08T10:22:03.123Z",
"name": "topic1"
}, {
"created_at": "2016-08-08T11:43:06.963Z",
"name": "topic2"
}]
}
for (var topic of json.all_topics) {
console.log(topic.created_at);
}
You can use JSON.stringify to turn a JavaScript object into a JSON String, and JSON.parse to turn a JSON string into a JavaScript object.
var jsonString = JSON.stringify(json);
==> {"all_topics":[{"created_at":"2016-08-08T10:22:03.123Z","name":"topic1"},{"created_at":"2016-08-08T11:43:06.963Z","name":"topic2"}]}
var jsonObj = JSON.parse(jsonString);
==> Object {all_topics: Array[2]}
Alternatively, you could return a new array with the filtered property using Array.prototype.map:
var topics = json.all_topics.map(function(obj){
return obj.created_at;
});
==> ["2016-08-08T10:22:03.123Z", "2016-08-08T11:43:06.963Z"]