Reputation: 71
I am having trouble and may be approaching this wrong so open to other solutions. From a fetch call, I am receiving a larger json array of objects which has further nesting in each object. I want to slim down the larger object array to only some values (for each object) and I am currently doing that by iterating over all of the objects in the larger array and taking the values I want from each object and then pushing to a newly created larger array. The below code works sometimes, however there are times where no data is present in some of the values from the json breaking my for loop. For exampledata.products[i].images[0].src
in a given object is sometimes undefined, which breaks the loop saying "cant read property .src of undefined" and doesn't iterate all the way through.
Main questions?
1. How can I account for undefined values in any given key:value pair without breaking the loop
2. Is there a better way to go about this entirely?
I can edit the answer to include an example of the incoming json if that helps at all
Edit
I also want to not include any object which resulted in undefined image in the final array. Is there any way to prevent that object from being added or maybe filter it out later?
let productFilter = []
fetch('https://some.json')
.then(
function (response) {
response.json().then(function (data) {
for (var i = 0; i < data.products.length; i++) {
let filteredArray = {
"productId": data.products[i].id,
"productName": data.products[i].title,
"productImg": data.products[i].images[0].src
}
productFilter.push(filteredArray)
}
});
}
)
.catch(function (err) {
console.log('Fetch Error', err);
})
Upvotes: 0
Views: 362
Reputation: 781096
use a conditional expression:
"productImg": data.products[i].images[0] ? data.products[i].images[0].src : "put default image URL here"
If you don't want these objects in the array at all, just put a test around the entire code that adds the object.
if (data.products[i].images[0]) {
let filteredArray = {
"productId": data.products[i].id,
"productName": data.products[i].title,
"productImg": data.products[i].images[0].src
}
productFilter.push(filteredArray)
}
Upvotes: 2
Reputation: 83537
For
exampledata.products[i].images[0].src
in a given object is sometimes undefined, which breaks the loop saying "cant read property .src of undefined"
The error tells you that exampledata.products[i].images[0]
is undefined
, not exampledata.products[i].images[0].src
itself. To deal with this, you can add a simple if statement inside your for loop:
let filteredArray = {
"productId": data.products[i].id,
"productName": data.products[i].title,
}
if (exampledata.products[i].images[0]) {
filteredArray.productImg = exampledata.products[i].images[0].src
}
Note that this solution will leave out the productImg
key when there is no image. Alternatively, you can use Barmar's answer if you want to ensure the key always exists and have an appropriate default, whether it is a default URL or just undefined
.
Suggestions:
Use a variable to shorten many lines in your code:
product = exampledata.products[i];
Now you can do product.id
, etc.
Check out the map()
function of Array. You can do the same thing you are doing here without writing all of the boilerplate code for the for
loop.
Upvotes: 0
Reputation: 707
You need to check if data.products[i] exists, otherwise you're attempting to reference properties of an undefined object. The same logic applies for the lower level reference to images[0].src
let productFilter = []
fetch('https://some.json')
.then(
function (response) {
response.json().then(function (data) {
for (var i = 0; i < data.products.length; i++) {
if (data.products[i]) {
let filteredArray = {
"productId": data.products[i].id,
"productName": data.products[i].title,
// "productImg": data.products[i].images[0].src
}
if (data.products[i].images[0]) {
filteredArray.productImg = data.products[i].images[0].src;
}
productFilter.push(filteredArray)
}
}
});
}
)
.catch(function (err) {
console.log('Fetch Error', err);
})
Upvotes: -1