How to extract data from JSON object - javascript

I am using Google Script to fetch an url that returns me the following JSON object:
[
{
"rsid":"op-bigideas",
"site_title":"Big Ideas",
"evars":[
{
"name":"Tracking Code",
"type":"text_string",
"id":"trackingcode",
"expiration_type":"week",
"expiration_custom_days":"1",
"allocation_type":"most_recent_last"
},
{
"name":"Custom eVar 1",
"description":"",
"type":"text_string",
"enabled":false,
"id":"evar1",
"expiration_type":"visit",
"expiration_custom_days":1,
"allocation_type":"most_recent_last"
}
]
}
]
How can I extract the name property from evars using javascript with Google Apps Script?
This is the code that returns me the JSON object:
var elements = JSON.parse(UrlFetchApp.fetch(url, options));
I already tried the following but only receiving undefined message:
1.
for(var elem in elements) {
Logger.log(elements[elem]['evars'].name);
}
2.
for(var elem in elements) {
Logger.log(elements[elem].evars.name);
}
3.
var newData = JSON.parse(elements);
Logger.log(newData.evars.name)

If I understand you correctly, you want to get the values of the name properties. This code will log the name properties:
for (var elem in elements) {
for (var evar in elements[elem].evars) {
Logger.log(elements[elem].evars[evar].name);
}
}
This will output:
"Tracking Code"
"Custom eVar 1"

There are multiple name properties for each element, so I think you want to map twice:
elements.map(function(elt) {
return !elt.evars ? [] : elt.evars.map(function(evar) {
return evar.name;
});
});
This will give you an array of arrays; the outer array is the elements, each of which contains an array of the names. For your example, this will be:
[
["Tracking Code", "Custom eVar 1"]
]

for (var elem in elements[0].evars) {
Logger.log(elements[0].evars[elem].name);
}

Related

How to work on dynamic properties of an array of objects in javascript? [duplicate]

If I have a JSON object like this:
{
"message": {
"name": { "stringLengthTooShort": "blub" }
}
}
The name of the property (here) stringLengthTooShort is changing every time,
how could I simply just get the child property of name with JS?
At the moment I have message.name but how could I get now the child of it?
if it's always the first property of message.name, you could do something like:
var keys = [];
for (var l in message.name) {
if (message.name.hasOwnProperty(l)){
keys.push(l);
}
}
//=>first property value should now be in message.name[keys[0]]);
// (its label is keys[0])
Edit: nine years after this answer all modern browsers support es20xx, so it's safe to use:
const obj = {
"message": {
"name": { "stringLengthTooShort": "blub" }
}
};
console.log(Object.keys(obj.message.name)[0]);

Converting xml request to json request with duplicate node names

I trying to push data to a 3rd party webservice, specifically converting the xml request to a json one (for use with node soap).
Here is an example of the raw xml request that works fine:
<EformData>
<EformFields>
<FieldName>txt_customername</FieldName>
<FieldValue>Scott</FieldValue>
</EformFields>
<EformFields>
<FieldName>txt_organisation</FieldName>
<FieldValue>My Orginisation</FieldValue>
</EformFields>
<EformFields>
<FieldName>txt_address</FieldName>
<FieldValue>My Address</FieldValue>
</EformFields>
<EformFields>
<FieldName>txt_telnumber</FieldName>
<FieldValue>123456</FieldValue>
</EformFields>
</EformData>
The problem i'm having is trying to convert these duplicate nodes into an object, the new object data is being overwritten with the last request.
Here's what i have so far:
var formValues = {
"txt_customername": "Scott",
"txt_organisation": "My Orginisation",
"txt_address": "My Address",
"txt_telnumber": "123456"
}
// Container
var EformData = {
"EformFields": {
}
};
// populate the object
for (var key in formValues) {
EformData.EformFields.FieldName = [key];
EformData.EformFields.FieldValue = formValues[key];
}
As you can see below, only the last request is stored in the object, the others are overwritten:
<EformData>
<EformFields>
<FieldName>txt_telnumber</FieldName>
<FieldValue>123456</FieldValue>
</EformFields>
</EformData>
Is it possible to build an object in such a way to match the orginal duplicate xml node data?
The data structure of your json should be that EformData has an array of EformFields objects, which has the properties of FieldName and FieldValue.
var formValues = {
"txt_customername": "Scott",
"txt_organisation": "My Orginisation",
"txt_address": "My Address",
"txt_telnumber": "123456"
}
// Container
var EformData = {
"EformFields": []
};
// populate the object
for (var key in formValues) {
EformData.EformFields.push({
"FieldName": key,
"FieldValue": formValues[key]
});
}
In your array, only 0th index is populated always and hence it is overrided when on the next iteration add an index for the array iteration as follows
// Container
var EformData = {
"EformFields": [
]
};
// populate the object
int i=0;
for (key in formValues) {
EformData.EformFields[i].FieldName = [key];
EformData.EformFields[i].FieldValue = formValues[key];
i++;
}

Javascript Key/Value Pairing with Arrays

I am trying to wrap my head around how I might accomplish something like this, structurally:
var keywordDataProducts =
[
{"keyword" : "keyword1", "list" : [ "DP1", "DP2" ] },
{"keyword" : "keyword2", "list" : [ "DP1" ] }
];
But of course, without the values being hard coded. For instance, we currently loop through all the DP values (DP1, DP2, DP3, etc..) - which all have 0-M keywords. I'm trying to create an inverse lookup of that, where you can get all DPs that use a particular keyword. I have code that uses the structure above perfectly, but I just need the data to get populated more dynamically.
Do I initialize the var keywordDataProducts = []; declaration with anything in it, or define the structure of it having a keyword and a list (which is an array)? Or do you leave it as an array with nothing about it, and define that when you're adding items?
I've heard associative arrays can be used for a situation like this, but I'm not quite wrapping my head around that at the moment. I've also seen objects with {} usages, but there is no push there and I need an array of keywords, which also contains arrays of DPs (list). Thoughts?
You would do something like this, but you didn't clearly describe what the input look like and what output you're looking for.
function fn (input) {
var ouput = {};
input.forEach( function (DP) {
for (prop in DP) {
if (DP.hasOwnProperty(prop) {
if (output[prop]) {
output[prop].push(DP);
} else {
output[prop] = [DP];
}
}
}
});
return output;
}
This takes this kind of input
[{"alpha":...}, {"beta":..., "delta":...}, {"alpha":..., "gamma":...}]
and returns
{"alpha":[{"alpha":...}, {"alpha":..., "gamma":...}]}, "beta":{"beta":..., "delta":...}, "delta":{"beta":..., "delta":...}, "gamma":{"alpha":..., "gamma":...}}
I don't know how you want your output so I just made an object with each keyword as its own key for the DP values.
var data = [{dp: "dp1", keys: ["key1", "key2", "key3"]}, {dp: "dp2", keys: ["key1", "key2", "key3"]}, {dp: "dp3", keys: ["key1", "key2", "key3"]},];
function keyWordArray(arr) {
var newObj = {};
arr.forEach((obj) => {
obj.keys.forEach((keyVal) => {
if(newObj.hasOwnProperty(keyVal)){
newObj[keyVal].dp.push(obj.dp);
} else {
newObj[keyVal] = {dp:[obj.dp],};
}
});
});
return newObj;
}
document.getElementById("data").innerHTML = JSON.stringify(keyWordArray(data));
<div id="data">
</div>
You can treat objects as associative arrays, and you don't have to use "push" to add a new element.
// Create your object like this
var keywordDataProducts =
{
"keyword1" : { "list" : [ "DP1", "DP2"] },
"keyword2" : { "list" : [ "DP1" ] }
};
// Treat it like an associative array
var keyword1 = keywordDataProducts["keyword1"];
alert("keyword1 = " + keyword1.list.join(", "));
// Add to it like this
keywordDataProducts["keyword3"] = { "list" : ["DP3", "DP4"] };
// See the new object includes your new keyword
alert(JSON.stringify(keywordDataProducts));
// To iterate the keys of your object, you can do something like this
for(var item in keywordDataProducts)
{
if(keywordDataProducts.hasOwnProperty(item))
{
alert(item);
}
}
You can see the fiddle here;
https://jsfiddle.net/gksjtwr6/2/

JSON Object many errors. Help out

I have made a JSON object and getting so many errors. I am new to JSON so kindly help. Posting here with the screenshots.
Any help would be appreciated.
[![var data\[\]= {"cars":
"Honda":\[
{"model":"Figo" },
{"model":"City"}
\],
"Audi": \[
{"model":"A6"},
{"model":"A8"}
\]
}
data.cars\['Honda'\]\[0\].model
data.cars\['Honda'\]\[1\].model
data.cars\['Audi'\]\[0\].model
ata.cars\['Audi'\]\[1\].model
for (var make in data.cars) {
for (var i = 0; i < data.cars\[make\].length; i++) {
var model = data.cars\[make\]\[i\].model;
alert(make + ', ' + model);
}
}][1]][1]
Using JSONformatter and validator site for checking my code.
Since you mentioned
I am totally novice for JSON
I would like to explain you this completely.
There are little bit of syntax errors in the way you are doing this. You are actually doing a for loop inside a javascript object which will obviously break. If your intention is to alert all the models of all the make, then here is how you do it..
initially you have this
var data = {
cars:{
"Honda":
[
{"model":"Figo" },
{"model":"City"}
],
"Audi":
[
{"model":"A6"},
{"model":"A8"}
]
}
}
You have a variable called data which is a object ({} refers to object) and this object has a property called cars and this property holds a object({} refers to object). Now this object has 2 properties Honda and Audi. Each of this properties are of type array ([] refers to array). And this each array further contains list of objects.
So once you are clear with the above point. Let manipulate the object you have.
Do a forloop to get all the properties of the cars object and when we have hold of each property lets loop its array and then extract the model property value.
for (var make in data.cars) {
for (var i = 0; i < data.cars[make].length; i++) {
var model = data.cars[make][i].model;
alert(make + ', ' + model);
}
}
Also dont get confused with Javascript Object and JSON....
In the above example the variable data is Javascript Object and when you do JSON.strinfigy(data) you are converting this Javascript object into string format and that string format is called JSON...
A Demo Fiddle to help you understand better.
Imho it's more like :
var cars = {
"Honda":
[
{"model":"Figo" },
{"model":"City"}
],
"Audi":
[
{"model":"A6"},
{"model":"A8"}
]
}
If you want a huge JSON object storing many cars attributes arrays.
Why do you use these "/" everywhere ?
(PS : if you wanna see some examples -> http://json.org/example.html)
I believe this is the structure your looking for:
cars={
make:{
honda:[
{
model:"accord",
color:"black",
cylinders: "6",
year:"2012"
},
{
model:"civic",
color:"white",
cylinders: "4",
year:"2015"
}
],
acura:[
{
model:"integra",
color:"red",
cylinders: "4",
year:"1992"
},
{
model:"RSX",
color:"Metallic Blue",
cylinders: "4",
year:"2016"
}
],
audi:[
{
model:"R8",
color:"white",
cylinders: "8",
year:"2015"
},
{
model:"A8",
color:"red",
cylinders: "8",
year:"2016"
}
]
}
};
document.addEventListener('DOMContentLoaded',()=>{
var models=[],colors=[],cylinder=[],year=[]; //INSTANTIATE ARRAYS
for(p in cars.make){ //LOOP THROUGH OBJECT PROPS (CARS.MAKE)
cars.make[p].forEach((o)=>{ //LOOP THROUGH (CARS.CARS.PROPS) PUSH OBJ INTO ARRAYS
models.push(o.model);
colors.push(o.color);
cylinders.push(o.cylinders);
year.push(o.year);
});
console.log(models);
console.log(colors);
console.log(cylinders);
console.log(year);
});

Angular ng-repeat: construct new object

var $scope.notif holds this data:
In a popup, I want to view the different messages, so I used:
<ion-list><ion-item ng-repeat="n in notif">{{n.msg}}</ion-item></ion-list>
While message 1 and message 2 are there, there are also 3 empty list items, probably because the length of the data is 5 because of the msg, msg_titleand notif_type.
Example showing the empty list items here.
Can I somehow tell Angular repeat the length minus 3?
I've tried removing the 3 extra items in the object using:
for(var i=0; i<($scope.notif.length); i++) {
$scope.notifnew.push($scope.notif[i]);
}
But $scope.notifnew is now undefined...
You can filter out properties that you don't like:
var data = test.notification.android.payload;
$scope.notif = Object.keys(data).filter(function(key){
return /^\d+$/.test(key); // or !!data[key].msg
}).map(function(key){
return data[key];
});
I've updated your plunker.
$scope.notif.length won't work because $scope.notif is an object not an array. You can iterate with:
var messages = [];
angular.forEach($scope.notif, function(val, key){
if (!isNaN(parseInt(key))) {
messages.push(val);
}
})
But this structure seems "broken" to me. Furthermore payload should be an array imo.
var test = {
"user_ids":["...","..."],
"notification":
{
"alert":"dummy",
"android":{
"title":"New alert 2",
"payload":{
"msg":"lala",
"msg_title":"Thanks!",
"notif_type":"alert",
"0":{
"msg":"Message 1"
},
"1":{
"msg":"Message 2","msg_title":"Thanks!"
}
}
}
}
}

Categories