У меня есть несколько компонентов в моем приложении vue.js, которые следуют приведенной ниже структуре, и все они выдают одну и ту же ошибку.
TypeError: Cannot read property 'id' of undefined
Я думал, что это будет легко исправить, обернув {{ jobs[0].id }}<template :v-if = "jobs"> или <template :v-if = "jobs[0].id">, поскольку большинство других сообщений о стеке переполнения указывают на это как на решение, но это действительно устраняет ошибки. Что интересно, в приведенном ниже коде все данные (включая идентификатор) отображаются на странице просто отлично, на странице нет данных, однако console.info продолжает показывать ошибку неопределенного свойства, и мои юнит-тесты терпят неудачу с тем же ошибка.
<template>
<div class = "emptyDiv">
<h3>
Latest Build -
<router-link:to = "{name: 'job_details'}">
{{ jobs[0].id }}
</router-link>
</h3>
</div>
<template>
<script>
export default {
name: "Stages",
data() {
return {
jobs: []
};
},
created() {
this.JobExecEndpoint =
process.env.VUE_APP_TEST_URL +
"/api/v2/job/"
fetch(this.JobExecEndpoint)
.then(response => response.json())
.then(body => {
this.cleanStartTime = moment(body[0].time_start);
this.cleanEndTime = moment(body[0].time_end);
this.cleanDuration = this.calculateDuration(
this.cleanStartTime,
this.cleanEndTime
);
this.jobs.push({
name: body[0].job.name,
id: body[0].id,
env: body[0].job.env,
time_start: this.cleanStartTime.format("LLL"),
time_end: this.cleanEndTime.format("LLL"),
duration: this.cleanDuration,
status: body[0].status.name,
job: body[0].job,
});
})
.catch(err => {
console.info("Error Fetching:", this.JobExecEndpoint, err);
return { failure: this.JobExecEndpoint, reason: err };
});
}
};
</script>
Что я здесь делаю неправильно? Я пытался устранить эти ошибки около 10 часов подряд и не смог понять это.
ОБНОВИТЬ:
Я смог избавиться от этих ошибок и пройти свои юнит-тесты, добавив
.then(() => {
this.new_id = this.jobs[0].id
})
в созданный блок и добавив new_id='' под данные
а затем вызов new_id из шаблона. Однако это неудовлетворительное решение, так как я до сих пор не знаю, почему он выдает ошибку с исходным кодом, и я не верю, что это решение будет работать с полным массивом (с более чем одним заданием).
build_id был опечаткой в моем посте, я исправил OP. у тела есть id. Это подтверждено, как уже упоминалось, идентификатор действительно отображается на странице, поэтому я не уверен.
консоль, и сбой модульного теста не укажет мне на конкретную строку
Я обновил оп с дополнительной информацией



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы упомянули, что пробовали <template :v-if = "jobs"> и <template :v-if = "jobs[0].id">, но ни один из них не решает проблему здесь. Во-первых, двоеточие перед v-if неверно, я предполагаю, что это просто опечатка в вопросе. Во-вторых, ни одно из этих условий на самом деле не нацелено на рассматриваемое значение undefined.
Сначала рассмотрим это:
<template v-if = "jobs">
Пустой массив считается правдивым, поэтому эта проверка всегда будет пройдена.
Тогда это:
<template v-if = "jobs[0].id">
У него точно такая же проблема, как и в исходном коде, он пытается получить доступ к свойству id первого элемента, а первым элементом является undefined. Вы не можете получить доступ к свойству undefined.
Что вам нужно, так это проверить, что первый элемент существует, поэтому что-то вроде этого:
<template v-if = "jobs[0]">
Или:
<template v-if = "jobs.length">
Или перепишите {{ jobs[0].id }} как:
{{ jobs[0] && jobs[0].id }}
Причина, по которой он отображается правильно, заключается в том, что страница будет повторно отображаться после того, как данные будут возвращены с сервера. Этот второй рендеринг завершится успешно, так как jobs теперь заполнен. Это первоначальный рендеринг, который терпит неудачу, прежде чем данные будут возвращены.
этот код {{ jobs[0] && jobs[0].id }} просто спас меня после часа поиска, спасибо!
В какой строке возникает ошибка? Это потому, что в теле нет поля
id, или это потому, что вы нажимаете его с помощью ключаbuild_id, но определяетеidв своем шаблоне?