Я использую сочетание нескольких технологий: функции Vue, Vuex, Vuetify, Google Firebase. Этот код работает нормально и обновляет компоненты после асинхронной загрузки данных с помощью моей собственной вызываемой функции firebase getBatchData () , но перед получением данных из firebase в консоли отображаются ошибки:
[Vue warn]: ошибка при рендеринге: «Ошибка типа: невозможно прочитать свойство 'location' из неопределенного"
Мой вопрос следующий - как показать какое-то значение перед тем, как фактические данные будут загружены асинхронно ?
// Действия Vuex (файл actions.js):
import * as EVENT from './mutation-types.js';
import firebase from "firebase/app";
const getBatchData = firebase.functions().httpsCallable('getBatchData');
function convertProjectSummary(values) {
let projects = [];
const projectNameCol = 0;
const locationCol = 1;
const len = values.length;
for (var i = 1; i < len; i++) {
let record = {};
record.project = values[i][projectNameCol];
record.location = values[i][locationCol];
projects.push(record);
}
return projects;
}
const actions = {
updateBatchData: (context) => {
context.commit(EVENT.SET_LOADING, {loading: true});
getBatchData().then(resp => {
let projectSummaryArray = [];
let projectSummarySheetName = 'Project Summary';
//separation ranges:
const valueRanges = JSON.parse(resp.data);
for (var i = 0; i < valueRanges.length; i++) {
if (range.includes(projectSummarySheetName)) {
projectSummaryArray = valueRanges[i].values;
continue;
};
};
let projectSummaryRecords = convertProjectSummary(projectSummaryArray);
//=> state.projectRecords:[],
context.commit(EVENT.UPDATE_PROJECT_SUMMARY, {projectRecords: projectSummaryRecords});
context.commit(EVENT.SET_LOADING, {loading: false});
}).catch(error => console.log(error))
}
}
export default actions
// Vuex getters (файл getters.js):
const getters = {
//getter function with parameter:
getProjectInfo: state => {
const records = state.projectRecords;
function searchProjectDate(projectName) {
if (records.length > 0) {
for(var i=0; i<records.length; i++) {
if(records[i].project == projectName) {
return records[i];
}
}
} /* not updated if use the next default value:
else {
return {
project: "data not available",
location: "data not available",
};
}
*/
}
//return a closure function
return searchProjectDate;
},
}
export default getters
// Vue projectInfo.vue file:
<template>
<!-- asynchronous computed value -->
<div><p :text="info.location"></p></div>
</template>
<script>
import { mapState, mapGetters} from "vuex";
export default {
name: "prj-info",
computed: {
...mapState(["currentProject"]),
...mapGetters(["getProjectInfo"]),
info() {
//getter function with parameter:
return this.getProjectInfo(this.currentProject);
}
}
}
</script>
Моя вина:
Вместо кода, который я предоставил, я использую дочерний компонент, и в нем была ошибка:
<template>
<!-- asynchronous computed value -->
<div><GreyTextField :text="summary && summary.location" /></div>
</template>
<template>
<div class="grey-textfield">
{{theText}}
</div>
</template>
<script>
export default {
name: "grey-textfield",
props: {
text: {
type: String,
default: "Text"
},
},
data() {
return {
theText: this.text
}
},
watch: {
text: function(val, oldVal) {
this.theText = val;
},
},
}
</script>
Я добавил наблюдателя для свойства текста. И теперь это работает. Сожалею. Иногда полезно поделиться кодом, чтобы найти ошибки.