Using Reduce To Loop Through JSON
Solution 1:
You need to check for undefined
values for the second object which doesn't have a property amountString
. In case, the property amountString
is not present in the object then return value 0
.
So change the return
statement from
return sum + elem.cost.amountString;
To
return sum + (elem.cost && elem.cost.amountString ? elem.cost.amountString : 0) ;
Complete Code:
var json = {};
json.data = [{
"id": 100,
"jobNumber": 1,
"jobTasks": [{
"id": 12,
"cost": {
"amountString": 100
}
},
{
"id": 13,
"cost": {
"amountString": 500
}
}
]
},
{
"id": 101,
"jobNumber": 2,
"jobTasks": [{
"id": 14,
"cost": {
"amountString": 100
}
},
{
"id": 15
}
]
}
]
json.data.forEach(function(item) {
var sum = item.jobTasks.reduce(function(sum, elem) {
return sum + (elem.cost && elem.cost.amountString ? elem.cost.amountString : 0) ;
}, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});
Solution 2:
TypeError: Cannot read property 'amountString' of undefined
That's happening because your are trying to dereference an undefined value. You are essentially writing return sum + undefined.amountString
, which is similar to writing return sum + null.amountString
. How do you get around this?
In addition to what Agalo suggested, we can filter on jobTask objects that do have a cost:
json.data.forEach(function(item) {
var sum = item.jobTasks
.filter(function (j) { return j.cost; })
.reduce(function(sum, elem) {
return sum + elem.cost.amountString;
}, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});
As an aside, consider using the arrow syntax, because it is arguably more readable.
json.data.forEach((item) => {
var sum = item.jobTasks
.filter((j) => j.cost)
.reduce((sum, elem) => sum + elem.cost.amountString, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});
Complete code listing:
var json = {};
json.data = [{
"id": 100,
"jobNumber": 1,
"jobTasks": [{
"id": 12,
"cost": {
"amountString": 100
}
},
{
"id": 13,
"cost": {
"amountString": 500
}
}
]
},
{
"id": 101,
"jobNumber": 2,
"jobTasks": [{
"id": 14,
"cost": {
"amountString": 100
}
},
{
"id": 15
}
]
}
];
// with traditional functions
json.data.forEach(function(item) {
var sum = item.jobTasks
.filter(function(j) {
return j.cost;
})
.reduce(function(sum, elem) {
return sum + elem.cost.amountString;
}, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});
// with arrow functions
json.data.forEach((item) => {
var sum = item.jobTasks
.filter((j) => j.cost)
.reduce((sum, elem) => sum + elem.cost.amountString, 0);
console.log('jobNumber' + item.jobNumber + ' ' + sum);
});
Post a Comment for "Using Reduce To Loop Through JSON"