Array as key and value but value is undefined - javascript

I don't know what's wrong with the code. it works fine and both array have data. but i don't understand why the output found undefined from var _city array as it passed data to the city field.
How can I fix this?
var city = {
_country : _city
};

I'm wondering what you read that made you possibly believe that by writing what you did you would magically have an object keyed with one array with values from a second...
Essentially what is happening when you did when you
var city = {
_country : _city
};
is create an object that looks like
var city = {
'_country' : ['your', 'array', 'of', 'cities']
};
that is to say, an object with one key, '_country' mapped to an array of cities.
This explains why you get undefined... city['any string that isn't exactly " _country"'] == undefined
What you want to do is more likely,
var city = _country.reduce(function(acc, cur, idx) { acc[cur] = _city[idx]; return acc; }, {});

It's because _country is already defined above:
var _country = ["Afghanistan","Bahrain","Canada","Denmark","Ethiopia","France","Germany","Hong Kong","India","Japan"];
Change the definition within city to something else (maybe country):
var city = {
country: _city,
};
And it'll work.

Related

Complex JSON obj and jQuery or Javascript map to specific key, value

I am banging my head trying to figure this out. And it should not be this hard. I am obviously missing a step.
I am pulling data from: openaq.org
The object I get back is based on a JSON object.
For now, I am using jQuery to parse the object and I am getting to the sub portion of the object that hold the specific parameter I want but I can't get to the specific key,value pair.
The object does not come back in the same order all the time. So when I tried to originally set up my call I did something like
obj.results.measurements[0].
Well since the obj can come back in an random order, I went back to find the key,value pair again and it was the wrong value, throwing my visual off.
That said, I have looked at use jQuery's find() on JSON object and for some reason can not get what I need from the object I am given by openaq.org.
One version of the object looks like this:
{"meta":{"name":"openaq-api","license":"CC BY 4.0d","website":"https://u50g7n0cbj.execute-api.us-east-1.amazonaws.com/","page":1,"limit":100,"found":1},"results":[{"location":"Metro Lofts","city":null,"country":"US","coordinates":{"latitude":39.731,"longitude":-104.9888},"measurements":[{"parameter":"pm10","value":49.9,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"pm1","value":24,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"um100","value":0,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um025","value":0.28,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um010","value":4.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"pm25","value":41.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"}]}]}
I am trying to get the "pm25" value.
The code I have tried is this:
function getAirQualityJson(){
$.ajax({
url: 'https://api.openaq.org/v2/latest?coordinates=39.73915,-104.9847',
type: 'GET',
dataType: "json"
// data: data ,
}).done(function(json){
console.log("the json is" + JSON.stringify(json));
console.log("the json internal is" + JSON.stringify(json.results));
var obj = json.results;
var pm25 = "";
//console.log(JSON.stringify(json.results.measurements[0]["parameter"]));
$.each(json.results[0], function(i,items){
//console.log("obj item:" + JSON.stringify(obj[0].measurements));
$.each(obj[0].measurements, function(y,things){
//console.log("each measurement:" + JSON.stringify(obj[0].measurements[0].value));//get each measurement
//pm 2.5
//Can come back in random order, get value from the key "pm25"
// pm25 = JSON.stringify(obj[0].measurements[2].value);
pm25 = JSON.stringify(obj[0].measurements[0].value);
console.log("pm25 is: " + pm25); // not right
});
});
//Trying Grep and map below too. Not working
jQuery.map(obj, function(objThing)
{ console.log("map it 1:" + JSON.stringify(objThing.measurements.parameter));
if(objThing.measurements.parameter === "pm25"){
// return objThing; // or return obj.name, whatever.
console.log("map it:" + objThing);
}else{
console.log("in else for pm25 map");
}
});
jQuery.grep(obj, function(otherObj) {
//return otherObj.parameter === "pm25";
console.log("Grep it" + otherObj.measurements.parameter === "pm25");
});
});
}
getAirQualityJson();
https://jsfiddle.net/7quL0asz/
The loop is running through I as you can see I tried [2] which was the original placement of the 'pm25' value but then it switched up it's spot to the 3rd or 4th spot, so it is unpredictable.
I tried jQuery Grep and Map but it came back undefined or false.
So my question is, how would I parse this to get the 'pm25' key,value. After that, I can get the rest if I need them.
Thank you in advance for all the help.
You can use array#find and optional chaining to do this,
because we are using optional chaining, undefined will be returned if a property is missing.
Demo:
let data = {"meta":{"name":"openaq-api","license":"CC BY 4.0d","website":"https://u50g7n0cbj.execute-api.us-east-1.amazonaws.com/","page":1,"limit":100,"found":1},"results":[{"location":"Metro Lofts","city":null,"country":"US","coordinates":{"latitude":39.731,"longitude":-104.9888},"measurements":[{"parameter":"pm10","value":49.9,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"pm1","value":24,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"um100","value":0,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um025","value":0.28,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um010","value":4.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"pm25","value":41.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"}]}]}
let found = data?.results?.[0]?.measurements?.find?.(
({ parameter }) => parameter === "pm25"
);
console.log(found);
You can iterate over measurements and find the object you need:
const data = '{"meta":{"name":"openaq-api","license":"CC BY 4.0d","website":"https://u50g7n0cbj.execute-api.us-east-1.amazonaws.com/","page":1,"limit":100,"found":1},"results":[{"location":"Metro Lofts","city":null,"country":"US","coordinates":{"latitude":39.731,"longitude":-104.9888},"measurements":[{"parameter":"pm10","value":49.9,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"pm1","value":24,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"um100","value":0,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um025","value":0.28,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um010","value":4.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"pm25","value":41.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"}]}]}';
const json = JSON.parse(data);
let value = null;
const measurements = json?.results?.[0]?.measurements ?? null;
if(measurements)
for (const item of measurements)
if (item.parameter === 'pm25') {
value = item.value;
break;
}
if (value) {
// here you can use the value
console.log(value);
}
else {
// here you should handle the case where 'pm25' is not found
}

How to fetch values from json array object without using object key name javascript?

Json Array Object
Through Ajax I will get dynamic data which is not constant or similar data based on query data will change. But I want to display charts so I used chartjs where I need to pass array data. So I tried below code but whenever data changes that code will break.
I cannot paste complete JSON file so after parsing it looks like this
[{"brand":"DUNKIN' DONUTS KEURIG","volume":1.9,"value":571757},{"brand":"MC CAFE","volume":1.1,"value":265096}];
You can use Object.keys and specify the position number to get that value
var valueOne =[];
var valueTwo = [];
jsonData.forEach(function(e){
valueOne.push(e[Object.keys(e)[1]]);
valueTwo.push(e[Object.keys(e)[2]]);
})
It seems like what you're trying to do is conditionally populate an array based the data you are receiving. One solution might be for you to use a variable who's value is based on whether the value or price property exist on the object. For example, in your forEach loop:
const valueOne = [];
jsonData.forEach((e) => {
const val = typeof e.value !== undefined ? e.value : e.average;
valueOne.push(val);
})
In your jsonData.forEach loop you can test existence of element by using something like:
if (e['volume']===undefined) {
valueone.push(e.price);
} else {
valueone.push(e.volume);
}
And similar for valuetwo...
You could create an object with the keys of your first array element, and values corresponding to the arrays you are after:
var data = [{"brand":"DUNKIN' DONUTS KEURIG","volume":1.9,"value":571757},{"brand":"MC CAFE","volume":1.1,"value":265096}];
var splitArrays = Object.keys(data[0]).reduce((o, e) => {
o[e] = data.map(el => el[e]);
return o;
}, {});
// show the whole object
console.log(splitArrays);
// show the individual arrays
console.log("brand");
console.log(splitArrays.brand);
console.log("volume");
console.log(splitArrays.volume);
// etc

The key value of one object is changing on update of other similar type of object in javascript

I am using two different array object initialPermissionArr[item.id] and newPermissionArr[roleId] in two different functions
function(item){
vm.initialPermissionArr[item.id] = item.permissions.map(function (permission) {
permission.status = true;
return permission;
});
}
staticArr[item.id] = item.permissions.map(function (permission) {
permission.status = true;
return permission;
});
newpermissionArr[item.id] = vm.initialPermissionArr[item.id];
Below function updates the array, if same object is found it updates the status and if new object is found it pushes to newPermissionArr
function onChanageOfPermission(roleId,item) {
var flag = false ;
for (var key in newpermissionArr[roleId]){
if(newPermissionArr[roleId][key].id == item.id){
flag = true;
newPermissionArr[roleId][key].status = item.status;
break;
}
}
if (!flag) {
newPermissionArr[roleId].push(item);
}
}
So when newPermissionArr[roleId][key].status = item.status; is updated it also update the status in the initialPermissionArr[item.id] also.
And initial declaration is
var newPermissionArr = [];
var staticArr = [];
where for eg item is
{
roleId : 1,
permissions : [{"name": "A", "id" : 1},{ "name" : "B", "id" : 2 }]
}
I need initial object Array to remain same and at the end i need to compare the initial array with the modified array and need to find the reference however on updating the status it updates in both array. How to avoid this ?
The arrays reference the same object. To modify just one of them, you should use slice() function for clone the array:
newpermissionArr[item.id] = vm.initialPermissionArr[item.id].slice();
This is happening because of following line of code
newpermissionArr[item.id] = vm.initialPermissionArr[item.id];
Here object is passed by reference, so whenever newpermission is updated intialpermission will also be updated.
To fix this just copy the intialPermissionArr to newPermissionArr.
Unfortunately,plain javascript does not have any function like angular.copy. So you will have to do this in following way-
newrPermissionArr[item.id] = JSON.parse(JSON.stringify(vm.intialPermissionArr[item.id]));
this should fix your problem.
When you assign something to a and b and it is a pointer in memory to object c. Then as soon as you change it to c2 both a and b will get c2 from that point as they were just pointers to same location.

converting each array value ias object in javascript not working

This is my array:
var country = ["US(+1)","IND(+91)"];
And i want to convert my array in this below format:
country = [
{
title: "US(+1)",
},
{
title: "IND(+91)",
}
]
word title should be same for each array value.
with this code am trying to get my expected result as above
var obj = country.reduce(function(o, val) { o['title'][] = val; return o; }, {});
But my output is comes like this as below: only last index is taking place
{"title":"IND(+91)"} this is wrong output which i dont want
You may be able to do it with reduce but it's much easier to use map:
var country = ["US(+1)","IND(+91)"];
var obj = country.map(function(c){return {title:c}});
console.log("country:", country);
console.log("obj:", obj);
map is for when you want to turn an array of things into another array of things, and reduce is when you want to turn an array of things into just a single thing.
var country = ["US(+1)","IND(+91)"];
I would use a more descriptive word since it is a list of countries.
var countries = ["US(+1)","IND(+91)"];
But to answer your question, to manipulate an array into a new array, I like to use the array.map method:
var objects = countries.map(function(country){ return { title: country } });
Here is the documentation for map:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map?v=control

Access the nested value in JSON without looping through it

This is my JSON, I want to directly get the zipCodes values from the JSON without looping through the JSON. How can I do it?
countries:[
{
name:'India',
states:[{
name:'Orissa',
cities:[{
name:'Sambalpur',
zipCodes:{'768019','768020'}
}]
}]
}
]
I think you are looking for
countries[0].states[0].cities[0].zipCodes
Please note, this works for the above JSON as there is only 1 country in countries array and same as for states and cities. However, if there are more than 1 country, state or city then, you will have to iterate to extract information until and unless you know the exact index.
As this is not an associative array, your option is only to use indexes like this:
countries[x].states[y].cities[0].zipCodes
Where x would be each representation of state in your array, in case, of course, that you have more than one.
Similarly y would be each state in each state in each country, in case you have more of those and you can do the same for cities if you need to.
EDIT:
Here's how you can iterate the array:
for(var c in countries)
{
var name = countries[c].name;
if (name === "CountryIAmLookingFor")
{
var statesList = countries[c].states;
for (var s in statesList)
{
var stateName = statesList[s].name;
.....
}
}
}
You can keep iterating until you find the country, state, and city you need, then extract the zipCodes from there as shown in the previous code snippet.
Without "looping"
You can do this crazy trick (not saying this is the best way, but this way you aren't looping through the JSON):
var myData = { 'Put Your Data': 'HERE' };
function getCodes(name, data) {
var sv = data.match(new RegExp(name+'([\\S\\s]*?}][\\S\\s]*?}])'))[1].match(/zipCodes":\[(.*?)\]/g), r = [];
sv.forEach(function (item) {
item.match(/\d+/g).forEach(function (sub) {
r.push(+sub);
});
});
return r;
}
getCodes('India', JSON.stringify(myData));
If your data is already string, then you don't need the JSON.stringify. The forEach you see isn't actually "looping" through the JSON. It's already extracted the zip codes and the code just adds the zip codes to the array. . This line:
var sv = JSON.stringify(data).match(new RegExp(name+'([\\S\\s]*?}][\\S\\s]*?}])'))[1].match(/zipCodes":\[(.*?)\]/g), r = [];
is what grabs the zip codes, it gets something like:
["zipCodes":["768019","768020"]"]
The next line:
item.match(/\d+/g)
will grab the numbers outputting something like:
["768019", "768020"]
The loop just adds the zip-codes to another array
With looping
You're better off looping through the JSON:
var myData = {}, // Your data
zips = [];
myData.countries.forEach(function(i) {
if (i.name === 'India') {
i.states.forEach(function(j) {
j.cities.forEach(function(l) {
l.zipCodes.forEach(function(m) {
zips.push(m);
});
});
});
}
});
//use "zips" array
PERFORMANCE AND SPEED TESTS
After testing copying an array about 500MB (half a gig) took about 30 seconds. That's a lot. Considering an extremely large JSON would be about ~5MB, looping through a little over 5MB of JSON takes about 0.14 seconds. You should never worry about speed.
Here's my "trick" for avoiding explicit iteration. Let JSON.parse or JSON.stringify do the work for you. If your JSON is in string form, try this:
var array = [];
JSON.parse(jsonString, function (key, value) {
if (key === "zipCodes") {
array = array.concat(value);
}
return value;
});
console.log(array); // all your zipCodes
Suppose your Json is like
countries =[
{
name:'India',
states:[{
name:'Orissa',
cities:[{
name:'Sambalpur',
zipCodes:768019768020
}]
},{
name:'mumbai',
cities:[{
name:'rea',
zipCodes:324243
}]
}]
}
]
So now we use MAP it will give you ZipCode of every cities
countries.map(function(s){
s.states.map(function(c){
c.cities.map(function(z){
console.log(z.zipCodes)
})
})
})
OR
If you use return statement then it will give you 2 array with two zip code as per over JSON
var finalOP = countries.map(function(s){
var Stalist = s.states.map(function(c){
var zip = c.cities.map(function(z){
return z.zipCodes
})
return zip
})
return Stalist
})
console.log(finalOP)

Categories