Can someone shed a light on why I keep getting errors for some objects and not for the others? After making an API call, response comes back with an array of 100.
items: Array(100)
0:
completeness: 5
country: ["Croatia"]
dataProvider: ["Croatian Academy of Sciences and Arts"]
dcLanguage: ["hr"]
dcLanguageLangAware: {def: Array(1)}
dcSubjectLangAware: {def: Array(2)}
dcTitleLangAware: {def: Array(1)}
dctermsSpatial: (2) ["http://sws.geonames.org/2950159/", "http://data.europeana.eu/place/base/2598"]
Not all items have the same properties, but for the ones that have e.g. dcSubjectLangAware I want to loop through them and output one of the variants to HTML (en, def or de). If there ain't none of those, output empty string.
let dcSubjectLangAware;
if (item.dcSubjectLangAware !== undefined) {
dcSubjectLangAware =
item.dcSubjectLangAware.en ||
item.dcSubjectLangAware.def[0] ||
item.dcSubjectLangAware.hr[0] ||
item.dcSubjectLangAware.def[1] ||
item.dcSubjectLangAware.de[0];
} else {
dcSubjectLangAware = '';
}
The problem arises when some items have dcSubjectLangAware but none of the values from the statement but e.g. .it or .fr. Instead of going to else and assigning an empty string to the variable, it throws an error that it can't read item.dcSubjectLangAware.def[0]. Of course it can't since def[0] doesn't exist for that item. Why doesn't it loop through the item.dcSubjectLangAware.def[1] || item.dcSubjectLangAware.de[0] and then goes to else? It does that for items that don't have any value (.en, def[0], def[1] or .de[0]) but when it stumbles upon an item that has some other value like .it[0,1,2] or multiple values that are defined like de and en
de: (3) ["Deutschland", "Europe", "Travels"]
en: ["Germany"]
it throws an error instead of picking one from if/else.
Error TypeError: Cannot read property '0' of undefined
at europeana - working.js:73
at Array.forEach (<anonymous>)
at updateUI (europeana - working.js:47)
at europeana - working.js:36
Line 73 is item.dcSubjectLangAware.def[0] from if/else. Or it stucks at item.dcSubjectLangAware.hr[0] and throws an error without checking item.dcSubjectLangAware.de[0] that is there...
All in all, it behaves very inconsistent. What is wrong here? Should the check somehow be different?
Unfortunately the conditional property operator ?.
will not be helpful here either. You will have to do something like this
let sla=item.dcSubjectLangAware,
dcSubjectLangAware =
sla && (
sla.en ||
sla.def&&sla.def[0] ||
sla.hr&&sla.hr[0] ||
sla.def&&sla.def[1] ||
sla.de&&sla.de[0]
) || 'Description not available.';
Just to clarify, a more thorough check that Carsten implemented was necessary, i.e. you have to check if there's .hr property and then also .hr[0] and so on.
For the sake of others and readability, here's if/else way:
let dcSubjectLangAware;
if (item.dcSubjectLangAware !== undefined) {
dcSubjectLangAware =
(item.dcSubjectLangAware && item.dcSubjectLangAware.en) ||
(item.dcSubjectLangAware.def && item.dcSubjectLangAware.def[0]) ||
(item.dcSubjectLangAware.hr && item.dcSubjectLangAware.hr[0]) ||
(item.dcSubjectLangAware.def && item.dcSubjectLangAware.def[1]) ||
(item.dcSubjectLangAware.de && item.dcSubjectLangAware.de[0]);
} else {
dcSubjectLangAware = 'Description not available.';
}