Currently, I am developing a Vue application that heavily relies on charts. The issue lies in the fact that I am fetching data from the database individually for each chart component, resulting in multiple calls and a slower page load time. I am looking to optimize this by fetching data from the database once and then passing it to each chart component via props. However, I have faced difficulties in implementing this approach.
Here is an example of the data structure:
https://i.sstatic.net/Lg4fk.png
In my main component, I retrieve data from another component that manages the API (called BIService). This main component also contains all the chart components.
<template>
<b-row cols="1" cols-sm="2" cols-lg="4">
<b-col class="mb-4">
<total-empty-units />
</b-col>
<b-col class="mb-4">
<vacancy-rent-loss />
</b-col>
<b-col class="mb-4">
<churn-rate />
</b-col>
<b-col class="mb-4">
<overdue-payments-chart />
</b-col>
</b-row>
</template>
<script>
import axios from '@/config/axios';
import {biService} from '@/services/bi';
import TotalEmptyUnits from '@/components/chart/empty-units/TotalEmptyUnits';
import OverduePaymentsChart from '@/components/chart/overdue-payments/OverduePaymentsChart';
import ChurnRate from '@/components/chart/churn-rate/ChurnRate';
import VacancyRentLoss from '@/components/chart/vacancy-loss/VacancyRentLoss';
export default {
components: {
TotalEmptyUnits,
OverduePaymentsChart,
ChurnRate,
VacancyRentLoss,
},
data: () => ({
bIGraphStats: null,
}),
methods: {
load() {
biService.getBIGraphStatsForCompany()
.then(result => this.bIGraphStats = result.data)
.catch(error => console.error(error));
},
},
};
</script>
As shown in the chart component example below, I am also making database calls within the individual chart components.
<template>
<b-card class="h-100" @click="showModal = true">
<div class="d-flex">
<h5 class="text-center flex-grow-1">Churn rate</h5>
<b-button variant="link" class="p-0">
<i class="fas fa-external-link-square-alt fa-lg"></i>
</b-button>
</div>
<apexchart
type="radialBar"
height="250"
:chartData="chartData"
:options="options"
:series="series">
</apexchart>
</b-card>
</template>
With the new approach, I have added a prop to the chart component named seriesData and attempted to pass it to the main component where the database data is fetched using a watcher. However, I am encountering an error "Cannot read properties of undefined" when trying to pass the data.
Below is a snippet of the updated code structure:
The main component:
<b-col class="mb-4">
<churn-rate v-if="loaded" :series-data="bIGraphStats" />
</b-col>
The chart component:
<template>
<b-card class="h-100" @click="showModal = true">
<div class="d-flex">
<h5 class="text-center flex-grow-1">Churn rate</h5>
<b-button variant="link" class="p-0">
<i class="fas fa-external-link-square-alt fa-lg"></i>
</b-button>
</div>
<apexchart
type="radialBar"
height="250"
:chartData="chartData"
:options="options"
:series="series">
</apexchart>
</b-card>
</template>