Reputation: 29
I am trying to fetch data from firebase before mounted() hook is called, but firebase query is asynchronous function and I'm struggling to handle those. Here is my code snippet:
<template>
<b-table-simple sticky-header="90%" class="table-bordered">
<b-thead head-variant="dark">
<b-tr>
<b-th >氏名</b-th>
<b-th v-for="date in printables" :key="date" class="text-center" v-html="date"></b-th>
</b-tr>
</b-thead>
<b-tbody v-if="fetched">
<template v-for="(staff_data, staff_id) in project.assigned_staff">
<b-tr :key="staff_id">
<b-th rowspan="6">
<b-tr>
<b-th rowspan="6" v-html="staff_data.name.split(/ | /).join('<br>')"></b-th>
<b-th >[]</b-th>
</b-tr>
<b-tr>
<b-th >出勤</b-th>
</b-tr>
<b-tr>
<b-th >残業</b-th>
</b-tr>
<b-tr>
<b-th >深夜</b-th>
</b-tr>
<b-tr>
<b-th >内容</b-th>
</b-tr>
<b-tr>
<b-th >弁当</b-th>
</b-tr>
</b-th>
<b-td v-for="i in days.length" :key="i">
<b-form-checkbox @change.native="setBGColor($event)" :ref="`select-${i}`"></b-form-checkbox>
</b-td>
</b-tr>
<b-tr :key="staff_id">
<b-td v-for="day in days" :key="day">
<b-form-select @change.native="setBGColor($event)" :ref="`regular-${staff_id}-${day}`" :options="regularTimeOption"></b-form-select>
</b-td>
</b-tr>
<b-tr :key="staff_id">
<b-td v-for="day in days" :key="day">
<b-form-select @change.native="setBGColor($event)" :ref="`overtime-${staff_id}-${day}`" :options="overTimeAndLateNightOption"></b-form-select>
</b-td>
</b-tr>
<b-tr :key="staff_id">
<b-td v-for="day in days" :key="day">
<b-form-select @change.native="setBGColor($event)" :ref="`latenight-${staff_id}-${day}`" :options="overTimeAndLateNightOption"></b-form-select>
</b-td>
</b-tr>
<b-tr :key="staff_id">
<b-td v-for="day in days" :key="day">
<b-form-select @change.native="setBGColor($event)" :ref="`type-${staff_id}-${day}`" :options="typeOption"></b-form-select>
</b-td>
</b-tr>
<b-tr :key="staff_id">
<b-td v-for="day in days" :key="day">
<b-form-select @change.native="setBGColor($event)" :ref="`bento-${staff_id}-${day}`" :options="bentoOption"></b-form-select>
</b-td>
</b-tr>
</template>
</b-tbody>
</b-table-simple>
<template>
//...
const project
export default {
beforeCreate() {
// fetching "project" which is necessary to determine table structure (laying out <b-tr>, <b-th> and <b-td>)
// this should be done before "mounted()" hook
firebase.database().ref(`/project/${projectId}`)
.once('value')
.then(...)
// fetching "daily_report" which is data to fill each <b-td>
// this should be executed after "project" is fetched
firebase.database().ref(`/daily_report/${projectId}`)
.once('value')
.then(snapShot => {
project = snapShot.val()
...
})
},
mounted() {
const elRegular = this.$refs[`regular-${postfix}`]
elRegular.value = report.hours_regular
},
//...
}
Desireble order for me is:
But because firebase.database().on() and once() are asynchronous functions, actual order will be:
The biggest problem here I think is fetching project completed after mounted() initiated. I searched about async/await and beforeRouteEnter guard of vue router, but none of them seems to solve my problem. How can I get promise-based functions done before mounted hook initiated?
Upvotes: 0
Views: 486
Reputation: 429
Instead of using an external variable, you should add it to the data
section of you component. This way, Vue can use it after the async call to Firebase.
export default {
data() {
project: {
// An empty array so Vue start with no lines,
// and add them once the array is populated.
assigned_staff: []
},
beforeCreate() {
// fetching "project" which is necessary to determine table structure
// (laying out <b-tr>, <b-th> and <b-td>)
// this should be done before "mounted()" hook
firebase.database().ref(`/project/${projectId}`)
.once('value')
.then(...)
// fetching "daily_report" which is data to fill each <b-td>
// this should be executed after "project" is fetched
firebase.database().ref(`/daily_report/${projectId}`)
.once('value')
.then(snapShot => {
// Set the property 'project' of the commponent
// to the value of the snapshot
this.$set(this, 'project', snapShot.val());
...
})
},
mounted() {
const elRegular = this.$refs[`regular-${postfix}`]
elRegular.value = report.hours_regular
},
...
}
Upvotes: 1