Uncaught TypeError: невозможно прочитать карту свойства undefined на объекте AJAX
Есть ли способ передать N/A по умолчанию, если нет результатов? Я хочу иметь возможность определить его как "N/A", если отображаемый объект пуст в заголовке.
Некоторые из предметов под Media_x0020_Specialist_x0028_s_x.results
return, но тогда некоторые предметы не возвращаются, и я получаю эту ошибку.
Код:
$.ajax({
url: requestUri,
type: "GET",
dataType: "json",
cache: false,
headers: {
accept: "application/json; odata=verbose"
},
success: function success(data) {
onSuccess(data);
ExportTable();
}
});
function onSuccess(data) {
var item = data.d.results;
for (var i = 0; i < item.length; i++) {
tableContent += "<tr>";
tableContent +=
"<td>" +
item[i].Franchises_x0020_with_x0020_Shar.results
.map(function(r) {
return r.Title;
})
.join("; ") +
"</td>";
tableContent +=
"<td>" + item[i].Stand_x0020_Alone_x0020_Franchis + "</td>";
tableContent +=
"<td>" +
item[i].Franchise_x0020_Liason.results
.map(function(r) {
return r.Title;
})
.join("; ") +
"</td>";
tableContent +=
"<td>" +
item[i].Media_x0020_Specialist_x0028_s_x.results
.map(function(r) {
return r.Title;
})
.join("; ") +
"</td>";
tableContent += "</tr>";
tableContent += "</tbody></thead>";
}
$("#title").append(tableContent);
}
2 ответа
Вы можете использовать тернарный оператор и повторить это для каждого элемента:
(item[i].Franchises_x0020_with_x0020_Shar.results ?
item[i].Franchises_x0020_with_x0020_Shar.results
.map(function(r) {
return r.Title;
})
.join("; ")
:
"N/A")
Лично я бы заключил это в круглые скобки, чтобы было понятнее, что происходит (как указано выше).
В качестве альтернативы, с новыми функциями javascript вы можете использовать дополнительную цепочку, которая была создана для решения этой самой проблемы:
item[i].Franchises_x0020_with_x0020_Shar?.results
.map(({ Title }) => Title))
.join("; ")
|| "N/A"
Дальнейший совет: у вас там много повторяющегося кода и объединение строк в javascript с помощью +
не так читабельно, как при использовании шаблонных литералов.
Вот решение, которое более лаконично, читаемо и может быть повторено для других данных, которые у вас могут быть:
$.ajax({
url: requestUri,
type: "GET",
dataType: "json",
cache: false,
headers: {
accept: "application/json; odata=verbose"
},
success: function success(data) {
onSuccess(data);
ExportTable();
}
});
// we'll reuse this function each time we want to get a semicolon-separated list of titles
function getFranchiseTitles(franchises) {
var noResultsMessage = 'N/A';
// is "results" present on this object? does it have length?
var hasResults = !!franchises.results && !!franchises.results.length;
// only attempt map if there are results to map over
return hasResults
? franchises.results.map(f => f.Title).join('; ')
: noResultsMessage;
}
function onSuccess(data) {
var results = data.d.results;
// map over results, instead of using a for loop
var tableRows = results.map(result => {
// destructure & rename each result to get child results
var {
Franchises_x0020_with_x0020_Shar: shared,
Stand_x0020_Alone_x0020_Franchis: standalone,
Franchise_x0020_Liason: liason,
Media_x0020_Specialist_x0028_s_x: specialist
} = result;
// get our titles from child objects
var sharedTitles = getFranchiseTitles(shared);
var standaloneTitles = getFranchiseTitles(standalone);
var liasonTitles = getFranchiseTitles(liason);
var specialistTitles = getFranchiseTitles(specialist);
// return markup for this table row with titles inserted
return `<tr>
<td>${sharedTitles}</td>
<td>${standaloneTitles}</td>
<td>${liasonTitles}</td>
<td>${specialistTitles}</td>
</tr>`
}).join('');
// wrap with outer table tags
var tableContent = `<table><tbody>${tableRows}</tbody></table>`;
// insert into element
$("#title").append(tableContent);
}