Cannot read property 'status' of undefined
Не могу понять, почему так происходит. Если я рандомно генерирую места в массиве parkingPlaces (закоментированный код) и, следовательно, в методе getPlacesFromDb не копирую полученный из firebase массив в массив parkingPlace, то все работает. Как только я делаю так, как в приведенном ниже коде, то получаю ошибку Cannot read property 'status' of undefined. Сначала я подумал, что не успевают данные с firebase подгрузиться и поэтому выдает ошибку, т.к. массив пустой. Поставил async, await. И ошибка та же. В чем может быть проблема?
async created() {
/* for (let i = 1; i <= 65; i++) {
let place = {
id: i,
status: Math.random() >= 0.5,
}
// Добавить
this.parkingPlaces.push(place)
} */
await this.getPlacesFromDb()
},
data() {
return {
name: '',
phone: '',
bookingDialog: false,
placeNumber: null,
bookingValid: false,
parkingPlaces: [],
receivedPlaces: [],
}
},
methods: {
getStatus(id) {
const sta = this.parkingPlaces[id - 1].status ? 'busy' : 'free'
//console.log("Парковка № ", id, " состояние: ", sta)
return sta
},
bookingPlace(id) {
console.log('Booking place ', id)
if (!this.parkingPlaces[id - 1].status) {
this.placeNumber = id
this.bookingDialog = true
}
},
changePlaceStatus(id) {
this.parkingPlaces[this.placeNumber - 1].status = true
let formData = {
name: this.name,
phone: this.phone,
id: this.placeNumber,
}
console.log(formData)
// Reset
this.bookingDialog = false
this.placeNumber = null
this.name = ''
this.phone = ''
},
getPlacesFromDb() {
let getPlaces = this.$fireDb.ref()
const receivedPlacesArray = []
getPlaces.on(
'value',
function (snapshot) {
const receivedPlaces = snapshot.val()
receivedPlaces.forEach((el) => {
let item = {
id: el.id,
status: el.status,
}
receivedPlacesArray.push(item)
})
},
function (error) {
console.log('Error: ' + error.code)
}
)
this.parkingPlaces = [...receivedPlacesArray]
},
},
async mounted() {
await this.getPlacesFromDb()
},
Ответы (1 шт):
Ошибка первая: await перед getPlacesFromDb() ничего не даст, поскольку getPlacesFromDb() не является асинхронным методом и не возвращает Promise.
Ошибка вторая: хуки created и mounted вызываются в момент создания и монтирования, однако сам компонент не будет ждать завершения обработки хуков! Поэтому если getPlacesFromDb() занимает продолжительное время, то хоть синхронно, хоть асинхронно пиши, но если остальные методы не могут обработать отсутствие данных, то будут вылетать ошибки.
Ошибка третья:
getPlacesFromDb() {
let getPlaces = this.$fireDb.ref()
const receivedPlacesArray = [] // 1) Объявили массив
getPlaces.on( // 2) Подписались на событие
'value',
function (snapshot) {
const receivedPlaces = snapshot.val()
receivedPlaces.forEach((el) => {
let item = {
id: el.id,
status: el.status,
}
receivedPlacesArray.push(item)
})
},
function (error) {
console.log('Error: ' + error.code)
}
)
// 3) ОШИБКА! Не факт, что данные уже пришли.
// Возможно тут копируется пустой массив.
this.parkingPlaces = [...receivedPlacesArray]
}
Третья ошибка в том, что результат никто не ждёт. Здесь у нас гонка, которой быть не должно.
Если я рандомно генерирую места в массиве parkingPlaces (закоментированный код) и, следовательно, в методе getPlacesFromDb не копирую полученный из firebase массив в массив parkingPlace, то все работает.
Это происходит потому, что в случае генерации у тебя массив наполняется шестидесяти пятью объектами и мы это видим. А в случае с применением getPlacesFromDb() массив, похоже, оказывается пустым.
Вообще сложно отладить код с гонками, не имея его весь у себя на компьютере. Надеюсь я смог помочь.