JSON - Accessing JSON Array and assigning variables - javascript

I have the following JSON in a file called census.json:
{
"areas": [
"UnitedStates", [{
"STATEORREGION": "United States",
"1910POPULATION": 92228531,
"1920POPULATION": 106021568,
"1930POPULATION": 123202660,
"1940POPULATION": 132165129,
"1950POPULATION": 151325798,
"1960POPULATION": 179323175,
"1970POPULATION": 203211926,
"1980POPULATION": 226545805,
"1990POPULATION": 248709873,
"2000POPULATION": 281421906,
"2010POPULATION": 308745538,
"1910CHANGE": 21,
"1920CHANGE": 15,
"1930CHANGE": 16.2,
"1940CHANGE": 7.3,
"1950CHANGE": 14.5,
"1960CHANGE": 18.5,
"1970CHANGE": 13.3,
"1980CHANGE": 11.5,
"1990CHANGE": 9.8,
"2000CHANGE": 13.2,
"2010CHANGE": 9.7
}],
"Alabama", [{
"STATEORREGION": "Alabama",
"1910POPULATION": 2138093,
"1920POPULATION": 2348174,
"1930POPULATION": 2646248,
"1940POPULATION": 2832961,
"1950POPULATION": 3061743,
"1960POPULATION": 3266740,
"1970POPULATION": 3444165,
"1980POPULATION": 3893888,
"1990POPULATION": 4040587,
"2000POPULATION": 4447100,
"2010POPULATION": 4779736,
"1910CHANGE": 16.9,
"1920CHANGE": 9.8,
"1930CHANGE": 12.7,
"1940CHANGE": 7.1,
"1950CHANGE": 8.1,
"1960CHANGE": 6.7,
"1970CHANGE": 5.4,
"1980CHANGE": 13.1,
"1990CHANGE": 3.8,
"2000CHANGE": 10.1,
"2010CHANGE": 7.5
}],
"Alaska", [{
"STATEORREGION": "Alaska",
"1910POPULATION": 64356,
"1920POPULATION": 55036,
"1930POPULATION": 59278,
"1940POPULATION": 72524,
"1950POPULATION": 128643,
"1960POPULATION": 226167,
"1970POPULATION": 300382,
"1980POPULATION": 401851,
"1990POPULATION": 550043,
"2000POPULATION": 626932,
"2010POPULATION": 710231,
"1910CHANGE": 1.2,
"1920CHANGE": -14.5,
"1930CHANGE": 7.7,
"1940CHANGE": 22.3,
"1950CHANGE": 77.4,
"1960CHANGE": 75.8,
"1970CHANGE": 32.8,
"1980CHANGE": 33.8,
"1990CHANGE": 36.9,
"2000CHANGE": 14,
"2010CHANGE": 13.3
}], ]
}
I am trying to access the different values stored in the array using the following:
$.getJSON("../data/census.json", function (json) {
var censusData = json;
console.log(censusData.areas);
});
This logs all the states to the console as an object, so I then tried to go down another level with:
$.getJSON("../data/census.json", function (json) {
var censusData = json;
console.log(censusData.areas.UnitedStates);
});
but this returns "undefined". How can I drill down another level? Ideally I would like to access each states population for a specific year and then assign it to a variable that I can use later.

the pattern here is after each string name we have an array of related information:
so you can convert it to an object like
var _result = {};
for ( var i=0;i<arr.length/2;i++){
_result[arr[i]] = arr[i+1];
}
then you can directly access those information by their string names
like this
censusData.areas.UnitedStates
will return an array after this transformation

There is currently no second level as there are commas instead of colons between the state names and their properties:
"Alaska", [{
"STATEORREGION":"Alaska",
"1910POPULATION":64356,
...
This makes the values "Alaska" and the dictionary of properties adjacent elements in a list. It seems what you want is:
"Alaska": [{
"STATEORREGION":"Alaska",
"1910POPULATION":64356,
...

your json data is invalid try this,
{"areas" : [
"UnitedStates", [{
"STATEORREGION":"United States",
"1910POPULATION":92228531,
"1920POPULATION":106021568,
"1930POPULATION":123202660,
"1940POPULATION":132165129,
"1950POPULATION":151325798,
"1960POPULATION":179323175,
"1970POPULATION":203211926,
"1980POPULATION":226545805,
"1990POPULATION":248709873,
"2000POPULATION":281421906,
"2010POPULATION":308745538,
"1910CHANGE":21,
"1920CHANGE":15,
"1930CHANGE":16.2,
"1940CHANGE":7.3,
"1950CHANGE":14.5,
"1960CHANGE":18.5,
"1970CHANGE":13.3,
"1980CHANGE":11.5,
"1990CHANGE":9.8,
"2000CHANGE":13.2,
"2010CHANGE":9.7
}],
"Alabama", [{
"STATEORREGION":"Alabama",
"1910POPULATION":2138093,
"1920POPULATION":2348174,
"1930POPULATION":2646248,
"1940POPULATION":2832961,
"1950POPULATION":3061743,
"1960POPULATION":3266740,
"1970POPULATION":3444165,
"1980POPULATION":3893888,
"1990POPULATION":4040587,
"2000POPULATION":4447100,
"2010POPULATION":4779736,
"1910CHANGE":16.9,
"1920CHANGE":9.8,
"1930CHANGE":12.7,
"1940CHANGE":7.1,
"1950CHANGE":8.1,
"1960CHANGE":6.7,
"1970CHANGE":5.4,
"1980CHANGE":13.1,
"1990CHANGE":3.8,
"2000CHANGE":10.1,
"2010CHANGE":7.5
}],
"Alaska", [{
"STATEORREGION":"Alaska",
"1910POPULATION":64356,
"1920POPULATION":55036,
"1930POPULATION":59278,
"1940POPULATION":72524,
"1950POPULATION":128643,
"1960POPULATION":226167,
"1970POPULATION":300382,
"1980POPULATION":401851,
"1990POPULATION":550043,
"2000POPULATION":626932,
"2010POPULATION":710231,
"1910CHANGE":1.2,
"1920CHANGE":-14.5,
"1930CHANGE":7.7,
"1940CHANGE":22.3,
"1950CHANGE":77.4,
"1960CHANGE":75.8,
"1970CHANGE":32.8,
"1980CHANGE":33.8,
"1990CHANGE":36.9,
"2000CHANGE":14,
"2010CHANGE":13.3
}]
]
}

So I was able to access the data by changing the structure of the JSON to the following:
{"areas" : [
[{
"STATEORREGION":"United States",
"POPULATION1910":92228531,
"1920POPULATION":106021568,
"1930POPULATION":123202660,
"1940POPULATION":132165129,
"1950POPULATION":151325798,
"1960POPULATION":179323175,
"1970POPULATION":203211926,
"1980POPULATION":226545805,
"1990POPULATION":248709873,
"2000POPULATION":281421906,
"2010POPULATION":308745538,
"1910CHANGE":21,
"1920CHANGE":15,
"1930CHANGE":16.2,
"1940CHANGE":7.3,
"1950CHANGE":14.5,
"1960CHANGE":18.5,
"1970CHANGE":13.3,
"1980CHANGE":11.5,
"1990CHANGE":9.8,
"2000CHANGE":13.2,
"2010CHANGE":9.7
}],
[{
"STATEORREGION":"Alabama",
"1910POPULATION":2138093,
"1920POPULATION":2348174,
"1930POPULATION":2646248,
"1940POPULATION":2832961,
"1950POPULATION":3061743,
"1960POPULATION":3266740,
"1970POPULATION":3444165,
"1980POPULATION":3893888,
"1990POPULATION":4040587,
"2000POPULATION":4447100,
"2010POPULATION":4779736,
"1910CHANGE":16.9,
"1920CHANGE":9.8,
"1930CHANGE":12.7,
"1940CHANGE":7.1,
"1950CHANGE":8.1,
"1960CHANGE":6.7,
"1970CHANGE":5.4,
"1980CHANGE":13.1,
"1990CHANGE":3.8,
"2000CHANGE":10.1,
"2010CHANGE":7.5
}],
[{
"STATEORREGION":"Alaska",
"1910POPULATION":64356,
"1920POPULATION":55036,
"1930POPULATION":59278,
"1940POPULATION":72524,
"1950POPULATION":128643,
"1960POPULATION":226167,
"1970POPULATION":300382,
"1980POPULATION":401851,
"1990POPULATION":550043,
"2000POPULATION":626932,
"2010POPULATION":710231,
"1910CHANGE":1.2,
"1920CHANGE":-14.5,
"1930CHANGE":7.7,
"1940CHANGE":22.3,
"1950CHANGE":77.4,
"1960CHANGE":75.8,
"1970CHANGE":32.8,
"1980CHANGE":33.8,
"1990CHANGE":36.9,
"2000CHANGE":14,
"2010CHANGE":13.3
}]
]
}
Then I used:
$.getJSON( "../data/census.json", function( json ) {
var censusData = json;
console.log(censusData.areas[0][0].POPULATION1910);
});
Also note that I had to change 1910POPULATION to POPULATION1910 in order to access it without getting an error. There may be a better way to do this than changing every key name for every state.
When I want to access the next state I just changed censusData[0][0] to censusData[1][0] and so on and so forth.

The string "United States" is the first element in a list.
The data for The United States is in censusData.areas[1]. The structure of the JSON looks a bit strange.

Related

How to model the rows in getData() since i have nested JSON data?

I want to display these fields :name, age, addresses_id, addresses_city, addresses_primary for each person into data studio.
My JSON data
{
"data": [
{
"name": "Lio",
"age": 30,
"addresses": [
{
"id": 7834,
"city": "ML",
"primary": 1
},
{
"id": 5034,
"city": "MM",
"primary": 1
}
]
},
{
"name": "Kali",
"age": 41,
"addresses": [
{
"id": 3334,
"city": "WK",
"primary": 1
},
{
"id": 1730,
"city": "DC",
"primary": 1
}
]
},
...
]
}
there is no problem if i don't render the addresses field
return {
schema: requestedFields.build(),
rows: rows
};
//rows:
/*
"rows": [
{
"values": ["Lio", 30]
},
{
"values": ["Kali", 41]
},
...
]
*/
The problem is
I'm not able to model the nested JSON data in Google Data Studio. I
have the problem exactly in the "addresses" field.
Could anyone tell me what format should be for the rows in this case?
As you already know, for each name of your dataset, you clearly have more than one row (one person has multiple addresses). Data Studio only accepts a single data for each field, since arrays are not supported at all. So you need to work on this.
There are some ways to solve this, but always keep in mind that:
getSchema() should return all available fields for your connector (the order doesn't really matter, since Data Studio always sort alphabetically the available fields)
getData() should return a list of values. But here the order is relevant: it should be the same as the parameter passed to getData() (which means the results should be dynamic, sometimes you'll return all values, sometimes not, and the order may change).
Solution 1: Return multiple rows per record
Since you can produce multiple rows for each name, just do it.
To achieve this, your field definition (=getSchema()) should include fields address_id, address_city and address_primary (you can also add address_order if you need to know the position of the address in the list).
Supposing getData() is called with all fields in the same order they were discribed, rows array should look like this:
"rows": [
{
"values": ["Lio", 30, "7834", "ML", 1]
},
{
"values": ["Lio", 30, "5034", "MM", 1]
},
{
"values": ["Kali", 41, "3334", "WK", 1]
},
{
"values": ["Kali", 41, "1730", "DC", 1]
},
...
]
IMO, this is the best solution for your data.
Solution 2: Return one address only, ignoring others
If you prefer one row per person, you can get one of the addresses and display only it (usually the main/primary address, or the first one).
To achieve this, your field definition (=getSchema()) should include fields address_id, address_city and address_primary.
Supposing getData() is called with all fields in the same order they were discribed, rows array should look like this:
"rows": [
{
"values": ["Lio", 30, "7834", "ML", 1]
},
{
"values": ["Kali", 41, "3334", "WK", 1]
},
...
]
Solution 3: Return all addresses, serialized in a field
This is helpful if you really need all information but do not want a complex scheme.
Just create a field called addresses in your field definition (=getSchema()) and write the JSON there as a string (or any other format you want).
Supposing getData() is called with all fields in the same order they were discribed, rows array should look like this:
"rows": [
{
"values": ["Lio", 30, "[{\"id\": 7834, \"city\": "ML", \"primary\": 1}, {\"id\": 5034, \"city\": \"MM\", \"primary\": 1}]"]
},
{
"values": ["Kali", 41, "[{\"id\": 3334, \"city\": \"WK\", \"primary\": 1}, {\"id\": 1730, \"city\": \"DC\", \"primary\": 1}]"]
},
...
]
This solution may appear senseless, but it is possible to interact with this data later in DataStudio using REGEX if really needed.
Solution 4: Create a different field for each address
If you're sure all records has a maximum number of addresses (in you example, both names have 2 addresses, for example), you can create multiple fields.
Your field definition (=getSchema()) should include fields address_id1, address_city1, address_primary1, address_id2, ... address_primaryN.
I wouldn't explain how rows should look like in this situation, but it is not hard to guess with the other examples.

Destructuring a json object in Javascript

How would access the _id and state values?
Here's the data
{
"data": {
"totalSamplesTested": "578841",
"totalConfirmedCases": 61307,
"totalActiveCases": 3627,
"discharged": 56557,
"death": 1123,
"states": [
{
"state": "Lagos",
"_id": "O3F8Nr2qg",
"confirmedCases": 20555,
"casesOnAdmission": 934,
"discharged": 19414,
"death": 207
},
{
"state": "FCT",
"_id": "QFlGp4md3y",
"confirmedCases": 5910,
"casesOnAdmission": 542,
"discharged": 5289,
"death": 79
}
]
}
}
What you have shown is a string in JSON format. You can convert that to a JavaScript object and then start to get the values you need from it.
let str = ‘{
"data": {
"totalSamplesTested": "578841",
"totalConfirmedCases": 61307,
"totalActiveCases": 3627,
"discharged": 56557,
"death": 1123,
"states": [
{
"state": "Lagos",
"_id": "O3F8Nr2qg",
"confirmedCases": 20555,
"casesOnAdmission": 934,
"discharged": 19414,
"death": 207
},
{
"state": "FCT",
"_id": "QFlGp4md3y",
"confirmedCases": 5910,
"casesOnAdmission": 542,
"discharged": 5289,
"death": 79
}
]
}
} ‘;
(Note, I have put the string in single quotes so it can be shown properly here but in your code you need to put it in back ticks so it can span many lines)
Now convert it to a JavaScript object.
let obj = JSON.parse(str);
Now look closely at the string to see how the object is structured. It actually has just one item in it, data. And that is itself an object with several items, one of which is states which is an array.
So, obj.data.states[0] is the array’s first entry. That is an object and has _id and state items.
You can step through the array extracting the ._id and .state entries.

Editing an object in nested data structure

I have a data structure like this:
var fieldTmp= [{
"CountryDetails":[{
"countryName":"Kerala",
"JobDetails":[{
"RequisitionId":"00020447961",
"City":"KOCHI",
"PostedDate":"2016-12-18"
},{
"RequisitionId":"26103",
"City":"TRIVANDRUM",
"PostedDate":"2016-12-12"
},{
"RequisitionId":"26077",
"City":"ALAPPEY",
"PostedDate":"2016-10-09"
},{
"RequisitionId":"00020774701",
"City":"KOTTAYAM",
"PostedDate":"2016-06-12"
},{
"RequisitionId":"26078",
"City":"ADOOR",
"PostedDate":"2016-05-19"}]
},
"countryName":"MADRAS",
"JobDetails":[{
"RequisitionId":"0025456",
"City":"CHENNAI",
"PostedDate":"2017-06-05"
},{
"RequisitionId":"69847562",
"City":"ADYAR",
"PostedDate":"2016-10-14"}]
},
{"countryName":"Tamil Nadu",
"JobDetails":[{
"RequisitionId":"00020550501",
"City":"CHENNAI",
"PostedDate":"2016-12-18"
},{
"RequisitionId":"00020786022",
"City":"KOVAI",
"PostedDate":"2016-09-01"
},{
"RequisitionId":"00020786071",
"City":"TRICHY",
"PostedDate":"2016-04-10"}]
}] }]
My requirement is, I need to add Job Details under MADRAS to Tamil Nadu and I need to sort the data based on one property -PostedDate.
So my result should be something like,
var fieldTmp= [{
"CountryDetails":[{
"countryName":"Kerala",
"JobDetails":[{
"RequisitionId":"00020447961",
"City":"KOCHI",
"PostedDate":"2016-12-18"
},{
"RequisitionId":"26103",
"City":"TRIVANDRUM",
"PostedDate":"2016-12-12"
},{
"RequisitionId":"26077",
"City":"ALAPPEY",
"PostedDate":"2016-10-09"
},{
"RequisitionId":"00020774701",
"City":"KOTTAYAM",
"PostedDate":"2016-06-12"
},{
"RequisitionId":"26078",
"City":"ADOOR",
"PostedDate":"2016-05-19"}]
},
{"countryName":"Tamil Nadu",
"JobDetails":[{
"RequisitionId":"0025456",
"City":"CHENNAI",
"PostedDate":"2017-06-05"
},{
"RequisitionId":"00020550501",
"City":"CHENNAI",
"PostedDate":"2016-12-18"
},{
"RequisitionId":"69847562",
"City":"ADYAR",
"PostedDate":"2016-10-14"
},{
"RequisitionId":"00020786022",
"City":"KOVAI",
"PostedDate":"2016-09-01"
},{
"RequisitionId":"00020786071",
"City":"TRICHY",
"PostedDate":"2016-04-10"}]
}] }]
I tried to extract Madras data and add that to under Tamil Nadu. But nothing is working.
I know how to extract single or multiple value from JSON object. But I need to edit that JSON and sort it. That I am able to do it.
I got the solution.
When the countryName is "Tamil Nadu" and "MADRAS",I extracted all the data and saved it in a new array using below code.
function mergingBothStateDetails(jsonJobDetails){
for(var j=0;j<jsonJobDetails.length;j++)
{
newTmpRecord.push({"RequisitionId":jsonJobDetails[j].RequisitionId,
"PostedDate":jsonJobDetails[j].PostedDate,
"City":jsonJobDetails[j].City});
}
}
Here newTmpRecord is an Array and is like universal variable
For sorting I used below codes
function sortNewList(){
newTmpRecord.sort(function(a, b){ // sort object by retirement date
var dateA=new Date(a.PostedDate), dateB=new Date(b.PostedDate)
return dateB-dateA //sort by date descending
});
}
You can simply extract the object "Madras" from the array and add all of its Jobdetails to the object "Tamil Nadu" in a for loop. You can either look where to add them in the loop by checking the dates, or you can write a sort function, which is pretty easy in javascript and well explained here:
You might want to look up objects
And here the sorting is explained.

PHP - json_decode giving NULL

I'm trying to use the advice given in How to search through a JSON Array in PHP to lookup country names based on a country code in a .json file.
I have a file, countrycodes.js which is formatted like this:
countries = [
{code: "GB", name: "United Kingdom"},
{code: "AF", name: "Afghanistan"},
// ...
{code: "ZM", name: "Zambia"},
{code: "ZW", name: "Zimbabwe"}
];
The variable, countries has to be there because part of the application relies on this.
In PHP I've done the following:
$str = file_get_contents('countrycodes.js');
var_dump($str);
This outputs a string:
string(9642) "countries = [
{code: "GB", name: "United Kingdom"},
{code: "AF", name: "Afghanistan"},
// ...
However, when I try and json_decode it, the following gives NULL:
$str = file_get_contents('countrycodes.js');
$json = json_decode($str);
var_dump($json);
I don't know why this is because json_decode accepts a string, and this is what's given on the link I posted above? I tried removing the JavaScript variable (countries = ) but this made no difference.
Ultimately what I want to do is be able to give PHP a country code such as 'GB' and get it to return the appropriate name e.g. 'United Kingdom'. My understanding of this is the json_decode part will need to work before this is possible.
For reference, the reason countries = was being used is for populating a <select> element based on advice given here: Populating select using ajax json array
If you json_decode returns null, this means the input string is not in a valid format. Your file contains a javascript variable and not a JSON string.
This is how the string should probably formatted:
{
"countries": [
{"code": "GB", "name": "United Kingdom"},
{"code": "AF", "name": "Afghanistan"},
{"code": "ZM", "name": "Zambia"},
{"code": "ZW", "name": "Zimbabwe"}
]
}
Extending on Jerodev's answer, if you cannot will not change the representation, you could do the following.
Modify your file so that you wrap the keys with quotes. Something like,
countries = [
{"code": "GB", "name": "United Kingdom"},
{"code": "AF", "name": "Afghanistan"},
// ...
{"code": "ZM", "name": "Zambia"},
{"code": "ZW", "name": "Zimbabwe"}
];
And then just decode the json part.
$str = file_get_contents('countrycodes.js');
$str = substr($str,12, strlen($str)-13); // do not include the semicolon
var_dump(json_decode($str));
However this is not a good approach, so I'd still suggest to look for other ways to populate the data in your element.
Note that 12 is the position where [ starts, if you have made any changes to variable names or spaces, that (and 13) needs to change.

Formatting JSON for Angular data binding

when my ajax call completes an array of json is returned
for my angular data binding to work perfectly, i need to merge all values in to a single JSON file. I have tried $.extend(), it's giving following output
Need a solution for this
for example if my response looks like this:
[0:"{'test':'test'}", 1:"{'test':'test'}", 2:"{'test':'test'}",3: "{'test':'test'}"];
the output i need is :
{ test':'test', 'test':'test', 'test':'test', 'test':'test' }
Edit:
The final value will be associated to the ng-model automatically.
desired output example:
{
"unique_id": 172,
"portfolio": "DIGITAL",
"bus_unit": "dummy",
"project_phase": "",
"test_phase": "SIT",
"project": "Google",
"golivedate": "03/09/2016",
"performance": "Green",
"summary": "jgnbfklgnflknflk",
"last_updated": "",
"risks_issues": "gfmngfnfglkj",
"project_start": "03/16/2016",
"batchLast_run": "",
"custom_project": "1",
"test_execution_id": 5456,
"unique_id": 172,
"test_execution_id": 5456,
"pass": 8,
"fail": 8,
"blocked": 8,
"in_progress": 8,
"no_run": 8,
"not_available": 0,
"total": 8
}
From what I understand you are trying to convert array of Json data into one singel json data. So you have array of values but you would want all of them in one variable. Try this
var testData = ["{'test':'test'}", "{'test':'test'}", "{'test':'test'}", "{'test':'test'}"];
var finalData ="";
$.each(testData,function(index,value){
finalData += value +',';
});
finalData = finalData.replace(/\},\{/g,',').slice(0, -1);
document.write(finalData);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Map just applies the function to every element in the array.
var arrayOfJSON = ...
var arrayOfObjects = arrayOfJSON.map(function (jsonString){
return JSON.parse(jsonString)
})
var jsonStringWithAllObjects = JSON.stringify(arrayOfObjects)
If you use underscore.js then can easily
like:
var list = [{"test1": "test1"}, {"test2": "test2"}, {"test3": "test3"}];
var newList = _.extend.apply(null,[{}].concat(list));
then output will be
{ test1: "test1", test2: "test2", test3: "test3" }
Iterate over the array, convert every value to a JSON object, concatenate and then convert to a string back.
If you need fo this more times, you probably should make this a function.

Categories

Resources