In a Nuxt.js project, I have a page where I need to do some client-side calculations before some data can be displayed in a table. Before, and during the calculation, I want to show a loading screen.
Some context: The data are plots used by a farmer. The table is supposed to show which crop was grown on a plot in the past years. The data is stored in the database is the following way:
plots = [{
name: 'Plot1',
year: 2017,
crop: 'Wheat'
...
}, {
name: 'Plot1',
year: 2018,
crop: 'Maize',
...
} ...]
In a method that data is converted into a nested Object of the following structure
data = {
'Plot1': {
2017: {
'crop': 'Wheat',
'catchCrop': true
},
2018: {
'crop': 'Maize',
'catchCrop': false
}
}
...
}
and subsequently displayed in the table component.
A mockup of the component looks like the following:
<template>
<loadingComponent v-if="loading"/>
<tableComponent v-else-if="!loading && dataAvailable"/>
<span v-else >No data</span>
</template>
<script>
data() {
return {
loading: true,
dataAvailable: false
}
},
mounted() {
this.startCalculation()
},
methods: {
startCalculation() {
if (store.data) {
// long running calculation, then
this.dataAvailable = true
}
this.loading = false
}
}
</script>
The problem I'm facing is that the loading component never shows.
However, the startCalculation method blocks the User Interface (which would be ok if the loading component was shown), and the component is only updated AFTER the calculation is finished.
Does anybody have an idea of how I could circumvent this? Thanks a lot in advance!
EDIT:
After fiddling around, I could get it to work the way I want by setting a setTimeout of 1ms. This way, the loading indicator is shown, the data is correctly processed and then the loading indicator is succesfully removed after the calculation finished. However, this feels like a really dirty hack and I would love to avoid it...
mounted() {
this.loading = true
// set short timeout in order for Vue to render the loading bar
setTimeout(() => {
this.startCalculation()
this.loading = false
},1)
}