Reputation: 49
I have an array returnedDocs
in code below (shortened via let returnedDocs = result.application.modules.module.moduleItem;
) that I got as response from API, it structure is pretty complex. Some nested objects are arrays some values are placed few levels deep in the structure.
I use filter method to get only those elements that got specific value.
let toFilterSix = returnedDocs.filter(
o =>
o.repeatableGroup.repeatableGroupItem.vocabularyReference
.vocabularyReferenceItem.formattedValue._text === "Abdomen"
);
this.filterArray6 = toFilterSix;
Normally it works fine but in below example one of repeatableGroupItem
is an array with two elements (image).
I've got an error due to fact that there is unexpected array within filtered objects:
Results.vue?82a0:202 Uncaught (in promise) TypeError: Cannot read property 'vocabularyReferenceItem' of undefined
at eval (Results.vue?82a0:202)
at Array.filter (<anonymous>)
at eval (Results.vue?82a0:201)
How can I avoid the error when do filter on other, non-array elements?
Here you can examine the data model, it's console.log'ed: https://lucid-villani-539a6f.netlify.com/results
Upvotes: 0
Views: 1769
Reputation: 21672
If you're trying to look for "Abdomen"
regardless of whether it's a single object or an array of those objects, you could use [].concat(repeatableGroupItem)
. This allows you to safely assume you're dealing with an array instead of handling each case individually.
From there you could use .some()
to determine if "Abdomen"
exists within any of the items.
// This array contains 4 objects...
// 1: repeatableGroupItem as single object, containing "Abdomen"
// 2: repeatableGroupItem as array of objects, containing "Abdomen"
// 3: repeatableGroupItem as single object, without "Abdomen"
// 4: repeatableGroupItem as array of objects, without "Abdomen"
const returnedDocs = [{ repeatableGroup: { repeatableGroupItem: { vocabularyReference: { vocabularyReferenceItem: { formattedValue: { _text: "Abdomen" } } } } } }, { repeatableGroup: { repeatableGroupItem: [{ vocabularyReference: { vocabularyReferenceItem: { formattedValue: { _text: "Abdomen" } } } }, { vocabularyReference: { vocabularyReferenceItem: { formattedValue: { _text: "Abdomen" } } } } ] } }, { repeatableGroup: { repeatableGroupItem: { vocabularyReference: { vocabularyReferenceItem: { formattedValue: { _text: "Not Abdomen" } } } } } }, { repeatableGroup: { repeatableGroupItem: [{ vocabularyReference: { vocabularyReferenceItem: { formattedValue: { _text: "Not Abdomen" } } } }, { vocabularyReference: { vocabularyReferenceItem: { formattedValue: { _text: "Not Abdomen" } } } } ] } }];
const result = returnedDocs.filter(o => {
const item = [].concat(o.repeatableGroup.repeatableGroupItem);
return item.some(i => i.vocabularyReference.vocabularyReferenceItem.formattedValue._text === "Abdomen");
});
//Logs items 1 and 2
console.log(result);
Upvotes: 0
Reputation: 781310
If you just want to ignore the arrays, you can simply test whether repeatableGroup
has a vocabularyReferences
property.
let toFilterSix = returnedDocs.filter(
o =>
o.repeatableGroup.repeatableGroupItem.vocabularyReference &&
o.repeatableGroup.repeatableGroupItem.vocabularyReference.vocabularyReferenceItem.formattedValue._text === "Abdomen"
);
If you want to search the array as well, you can use an if
statement to search that when it's an array.
let toFilterSix = returnedDocs.filter(
o => {
if (Array.isArray(o.repeatableGroup.repeatableGroupItem)) {
return o.repeatableGroup.repeatableGroupItem.some(el => el.vocabularyReference.vocabularyReferenceItem.formattedValue._text === "Abdomen");
} else {
return o.repeatableGroup.repeatableGroupItem.vocabularyReference.vocabularyReferenceItem.formattedValue._text === "Abdomen";
}
});
Upvotes: 1