On the outermost level, a JSON object starts with a { and end with a }.
Sample data:
{
"cars": {
"Nissan": [
{"model":"Sentra", "doors":4},
{"model":"Maxima", "doors":4},
{"model":"Skyline", "doors":2}
],
"Ford": [
{"model":"Taurus", "doors":4},
{"model":"Escort", "doors":4}
]
}
}
If the JSON is assigned to a variable called data, then accessing it would be like the following:
data.cars['Nissan'][0].model // Sentra
data.cars['Nissan'][1].model // Maxima
data.cars['Nissan'][2].doors // 2
for (var make in data.cars) {
for (var i = 0; i < data.cars[make].length; i++) {
var model = data.cars[make][i].model;
var doors = data.cars[make][i].doors;
alert(make + ', ' + model + ', ' + doors);
}
}
Another approach (using an associative array for car models rather than an indexed array):
{
"cars": {
"Nissan": {
"Sentra": {"doors":4, "transmission":"automatic"},
"Maxima": {"doors":4, "transmission":"automatic"}
},
"Ford": {
"Taurus": {"doors":4, "transmission":"automatic"},
"Escort": {"doors":4, "transmission":"automatic"}
}
}
}
data.cars['Nissan']['Sentra'].doors // 4
data.cars['Nissan']['Maxima'].doors // 4
data.cars['Nissan']['Maxima'].transmission // automatic
for (var make in data.cars) {
for (var model in data.cars[make]) {
var doors = data.cars[make][model].doors;
alert(make + ', ' + model + ', ' + doors);
}
}
Edit:
Correction: A JSON object starts with { and ends with }, but it's also valid to have a JSON array (on the outermost level), that starts with [ and ends with ].
Also, significant syntax errors in the original JSON data have been corrected: All key names in a JSON object must be in double quotes, and all string values in a JSON object or a JSON array must be in double quotes as well.
See:
- JSON specification
- JSONLint - The JSON validator
On the outermost level, a JSON object starts with a { and end with a }.
Sample data:
{
"cars": {
"Nissan": [
{"model":"Sentra", "doors":4},
{"model":"Maxima", "doors":4},
{"model":"Skyline", "doors":2}
],
"Ford": [
{"model":"Taurus", "doors":4},
{"model":"Escort", "doors":4}
]
}
}
If the JSON is assigned to a variable called data, then accessing it would be like the following:
data.cars['Nissan'][0].model // Sentra
data.cars['Nissan'][1].model // Maxima
data.cars['Nissan'][2].doors // 2
for (var make in data.cars) {
for (var i = 0; i < data.cars[make].length; i++) {
var model = data.cars[make][i].model;
var doors = data.cars[make][i].doors;
alert(make + ', ' + model + ', ' + doors);
}
}
Another approach (using an associative array for car models rather than an indexed array):
{
"cars": {
"Nissan": {
"Sentra": {"doors":4, "transmission":"automatic"},
"Maxima": {"doors":4, "transmission":"automatic"}
},
"Ford": {
"Taurus": {"doors":4, "transmission":"automatic"},
"Escort": {"doors":4, "transmission":"automatic"}
}
}
}
data.cars['Nissan']['Sentra'].doors // 4
data.cars['Nissan']['Maxima'].doors // 4
data.cars['Nissan']['Maxima'].transmission // automatic
for (var make in data.cars) {
for (var model in data.cars[make]) {
var doors = data.cars[make][model].doors;
alert(make + ', ' + model + ', ' + doors);
}
}
Edit:
Correction: A JSON object starts with { and ends with }, but it's also valid to have a JSON array (on the outermost level), that starts with [ and ends with ].
Also, significant syntax errors in the original JSON data have been corrected: All key names in a JSON object must be in double quotes, and all string values in a JSON object or a JSON array must be in double quotes as well.
See:
- JSON specification
- JSONLint - The JSON validator
A good book I'm reading: Professional JavaScript for Web Developers by Nicholas C. Zakas 3rd Edition has the following information regarding JSON Syntax:
"JSON Syntax allows the representation of three types of values".
Regarding the one you're interested in, Arrays it says:
"Arrays are represented in JSON using array literal notation from JavaScript. For example, this is an array in JavaScript:
var values = [25, "hi", true];
You can represent this same array in JSON using a similar syntax:
[25, "hi", true]
Note the absence of a variable or a semicolon. Arrays and objects can be used together to represent more complex collections of data, such as:
{
"books":
[
{
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
"edition": 3,
"year": 2011
},
{
"title": "Professional JavaScript",
"authors": [
"Nicholas C.Zakas"
],
"edition": 2,
"year": 2009
},
{
"title": "Professional Ajax",
"authors": [
"Nicholas C. Zakas",
"Jeremy McPeak",
"Joe Fawcett"
],
"edition": 2,
"year": 2008
}
]
}
This Array contains a number of objects representing books, Each object has several keys, one of which is "authors", which is another array. Objects and arrays are typically top-level parts of a JSON data structure (even though this is not required) and can be used to create a large number of data structures."
To serialize (convert) a JavaScript object into a JSON string you can use the JSON object stringify() method. For the example from Mark Linus answer:
var cars = [{
color: 'gray',
model: '1',
nOfDoors: 4
},
{
color: 'yellow',
model: '2',
nOfDoors: 4
}];
cars is now a JavaScript object. To convert it into a JSON object you could do:
var jsonCars = JSON.stringify(cars);
Which yields:
"[{"color":"gray","model":"1","nOfDoors":4},{"color":"yellow","model":"2","nOfDoors":4}]"
To do the opposite, convert a JSON object into a JavaScript object (this is called parsing), you would use the parse() method. Search for those terms if you need more information... or get the book, it has many examples.
Here I use forEach() to iterate through the array and check each object if it has a value in gender property. If it doesn't then give it a value "male".
var info = [{
"name" : "john",
"address" : "32 street, london",
"contact" : 123456
},{
"name" : "jeyy",
"address" : "51 street, new york",
"contact" : 987654321,
"gender" : "male"
},{
"name" : "robert",
"address" : "14th street, birmingham",
"contact" : 456123789,
"gender" : "male"
},{
"name" : "carlos",
"address" : "89th street, manchester",
"contact" : 23456
},{
"name": "johnny",
"address": "6th street, Washington",
"contact": 23456
},{
"name": "jack",
"address": "4th street, VA",
"contact": 23456,
"gender": "male"
}
];
info.forEach(i => {
if(!i.gender) i.gender = "male";
});
console.log(info);
You can use .hasOwnProperty on that object to find out which object don't have property gender and iteratively add it and write back into the file again!
Here's a code snippet to help you get started.
const fs = require('fs');
const util = require('util');
// Promisify fs api(s)
const readFileAsync = util.promisify(fs.readFile);
const writeFileAsync = util.promisify(fs.writeFile);
// IIFE to read the file, find the objects which has missing properties, add them and write them back
(async function() {
try {
const fileContents = await readFileAsync('data.json');
const fileData = JSON.parse(fileContents);
const remainingData = fileData.filter(x => !x.hasOwnProperty('gender'));
remainingData.forEach(x => x.gender = 'Male');
await writeFileAsync('data.json', JSON.stringify(fileData, null, 4));
} catch(err) {
console.log(`Failed because: {err}!`)
}
})();
function findPrices(res) {
(api.get({
origin: A,
destination: B,
}).then(function(response) {
let data = []
try {
// read the data and convert into json
data = fs.readFileSync('api/data/destinations3.json', 'utf8')
data = JSON.parse(data)
data = Array.isArray(data) ? data : [data]
} catch(err) {}
const responseData = response.result.data
const priceSearch1Array = JSON.stringify([ ...data, responseData ])
fs.writeFileSync('api/data/destinations3.json', priceSearch1Array);
}).catch(function(error) {
console.log('error and continue' + error);
}))
}
I think that perhaps the structure of the code is what's making this slightly confusing to debug. I've reformatted things for this example but it's not essential to solve the problem that you're experiencing.
There are two problems that I think may be causing the issues with this.
Firstly, we're getting an array of arrays of objects, when we actually want an array of objects. This is easy enough to solve if you flatten the array as shown in the function below.
Secondly, we're writing the raw object to file. As I understand it, and from some testing I've done, fs is going to write the data you pass it to file as a string. That means that it'll use a fairly simplistic conversion, and your objects will come out as [Object object] as you saw. To get around this, we can use JSON.stringify to get a more appropriate conversion. I've simulated the fs and api calls, but the example gives you a rough idea.
I've also converted this to use map and Promise.all instead of pushing to an array from a loop. I feel it's a little easier to understand this way, if it doesn't make sense, please feel free to comment and I'll go into more detail.
const api = {
get: data => new Promise(res => {
setTimeout(() => res([data]), 1000)
})
}
const fs = {
writeFileSync: (location, data) => {
console.log(
`writing data ${data} to ${location}`
);
console.log('=====================');
}
}
const data = [
{A: 'test', B: 'another test'},
{A: 'test2', B: 'another test2'},
];
const makeApiCallFromDataItem = dataItem => api.get({
origin: dataItem.A,
destination: dataItem.B,
});
const callApiForAllDataItems = data => Promise
.all(data.map(makeApiCallFromDataItem))
const flatten = dataIn => dataIn.reduce((prev, curr) => [
...prev,
...curr
])
callApiForAllDataItems(data)
.then(data => {
fs.writeFileSync('api/data/destinations3.json', data)
})
callApiForAllDataItems(data)
.then(data => {
fs.writeFileSync('api/data/destinations3.json', JSON.stringify(data))
})
callApiForAllDataItems(data)
.then(data => {
const flatData = flatten(data);
fs.writeFileSync('api/data/destinations3.json', JSON.stringify(flatData))
})
You want the concat method.
var finalObj = json1.concat(json2);
Upon first appearance, the word "merg" leads one to think you need to use .extend, which is the proper jQuery way to "merge" JSON objects. However, $.extend(true, {}, json1, json2); will cause all values sharing the same key name to be overridden by the latest supplied in the params. As review of your question shows, this is undesired.
What you seek is a simple javascript function known as .concat. Which would work like:
var finalObj = json1.concat(json2);
While this is not a native jQuery function, you could easily add it to the jQuery library for simple future use as follows:
;(function($) {
if (!$.concat) {
$.extend({
concat: function() {
return Array.prototype.concat.apply([], arguments);
}
});
}
})(jQuery);
And then recall it as desired like:
var finalObj = $.concat(json1, json2);
You can also use it for multiple array objects of this type with a like:
var finalObj = $.concat(json1, json2, json3, json4, json5, ....);
And if you really want it jQuery style and very short and sweet (aka minified)
;(function(a){a.concat||a.extend({concat:function(){return Array.prototype.concat.apply([],arguments);}})})(jQuery);
;(function($){$.concat||$.extend({concat:function(){return Array.prototype.concat.apply([],arguments);}})})(jQuery);
$(function() {
var json1 = [{id:1, name: 'xxx'}],
json2 = [{id:2, name: 'xyz'}],
json3 = [{id:3, name: 'xyy'}],
json4 = [{id:4, name: 'xzy'}],
json5 = [{id:5, name: 'zxy'}];
console.log(Array(10).join('-')+'(json1, json2, json3)'+Array(10).join('-'));
console.log($.concat(json1, json2, json3));
console.log(Array(10).join('-')+'(json1, json2, json3, json4, json5)'+Array(10).join('-'));
console.log($.concat(json1, json2, json3, json4, json5));
console.log(Array(10).join('-')+'(json4, json1, json2, json5)'+Array(10).join('-'));
console.log($.concat(json4, json1, json2, json5));
});
center { padding: 3em; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<center>See Console Log</center>
jsFiddle
JSON is just a notation; to make the change you want parse it so you can apply the changes to a native JavaScript Object, then stringify back to JSON
var jsonStr = '{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}';
var obj = JSON.parse(jsonStr);
obj['theTeam'].push({"teamId":"4","status":"pending"});
jsonStr = JSON.stringify(obj);
// "{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"},{"teamId":"4","status":"pending"}]}"
var Str_txt = '{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}';
If you want to add at last position then use this:
var parse_obj = JSON.parse(Str_txt);
parse_obj['theTeam'].push({"teamId":"4","status":"pending"});
Str_txt = JSON.stringify(parse_obj);
Output //"{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"},{"teamId":"4","status":"pending"}]}"
If you want to add at first position then use the following code:
var parse_obj = JSON.parse(Str_txt);
parse_obj['theTeam'].unshift({"teamId":"4","status":"pending"});
Str_txt = JSON.stringify(parse_obj);
Output //"{"theTeam":[{"teamId":"4","status":"pending"},{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"3","status":"member"}]}"
Anyone who wants to add at a certain position of an array try this:
parse_obj['theTeam'].splice(2, 0, {"teamId":"4","status":"pending"});
Output //"{"theTeam":[{"teamId":"1","status":"pending"},{"teamId":"2","status":"member"},{"teamId":"4","status":"pending"},{"teamId":"3","status":"member"}]}"
Above code block adds an element after the second element.
I found very good link for JSON: http://code.google.com/p/json-simple/wiki/EncodingExamples#Example_1-1_-_Encode_a_JSON_object
Here's code to add multiple JSONObjects to JSONArray.
JSONArray Obj = new JSONArray();
try {
for(int i = 0; i < 3; i++) {
// 1st object
JSONObject list1 = new JSONObject();
list1.put("val1",i+1);
list1.put("val2",i+2);
list1.put("val3",i+3);
obj.put(list1);
}
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Toast.makeText(MainActivity.this, ""+obj, Toast.LENGTH_LONG).show();
Once you have put the values into the JSONObject then put the JSONObject into the JSONArray staright after.
Something like this maybe:
jsonObj.put("value1", 1);
jsonObj.put("value2", 900);
jsonObj.put("value3", 1368349);
jsonArray.put(jsonObj);
Then create new JSONObject, put the other values into it and add it to the JSONArray:
jsonObj.put("value1", 2);
jsonObj.put("value2", 1900);
jsonObj.put("value3", 136856);
jsonArray.put(jsonObj);
No point in having each person object wrapped inside it's own array. Unless there is some other grouping that needs done all you should need is one array that contains all the person objects
result: [
{
"name": "Josh",
"age": 15
},
{
"name": "Joe",
"age": 16
}
]
This array can be sorted by ages or names, filtered etc
If you want to keep object like that, something like this work. pleases try this one
var pList = {
people: [{
'name': 'Josh',
'age': 15
}, {
'name': 'Joe',
'age': 16
}],
animal: [{
'type': 'Dog',
'legs': 4
}, {
'type': 'Bird',
'legs': 2
}]
};
[].forEach.call(pList.people, function(p) {
// can push its value into new array or else
console.log(`${p.name} -- ${p.age}`);
})
//or
pList.animal.forEach(function(a) {
console.log(`${a.type} -- ${a.legs}`)
})