Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
vue component won't wait for data from controller using axios get, it prompt error:
index.vue?d4c7:200 Uncaught (in promise) TypeError: Cannot read property 'ftth' of undefined
my code are below:
<template>
<div class="dashboard-editor-container">
<el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;">
<line-chart :chart-data="lineChartData"/>
</el-row>
</template>
<script>
import LineChart from './components/LineChart';
import axios from 'axios';
const lineChartData = {
all: {
FTTHData: [],
VDSLData: [],
ADSLData: [],
export default {
name: 'Dashboard',
components: {
LineChart,
data() {
return {
lineChartData: lineChartData.all,
created() {
this.getData();
methods: {
handleSetLineChartData(type) {
this.lineChartData = lineChartData[type];
async getData() {
axios
.get('/api/data_graphs')
.then(response => {
console.log(response.data);
var data = response.data;
var i = 0;
for (i = Object.keys(data).length - 1; i >= 0; i--) {
lineChartData.all.FTTHData.push(data[i]['ftth']);
lineChartData.all.VDSLData.push(data[i]['vdsl']);
lineChartData.all.ADSLData.push(data[i]['adsl']);
</script>
Do I have to use watch method?
–
–
First, because you have such a nested data structure you'll want a computed property to return whether the data is loaded or not. Normally, you could do this check in the template.
computed: {
isDataLoaded() {
const nestedLoaded = Object.keys(this.lineChartData).map(key => this.lineChartData[key].length !== 0)
return this.lineChartData && nestedLoaded.length !== 0
You can use v-if="isDataLoaded"
to hide the element until the data has been loaded.
–
–
It is not exactly clear how response.data
looks like, but because you're using Object.keys
I'm assuming it's an object.
If you need to loop over the keys then when using numeric indexes you most likely won't get an object. So you need to get the key
and index i
and use that value to access the object. Change this:
for (i = Object.keys(data).length - 1; i >= 0; i--) {
lineChartData.all.FTTHData.push(data[i]['ftth']);
lineChartData.all.VDSLData.push(data[i]['vdsl']);
lineChartData.all.ADSLData.push(data[i]['adsl']);
to this:
const keys = Object.keys(data)
for (i = keys.length - 1; i >= 0; i--) {
lineChartData.all.FTTHData.push(data[keys[i]]['ftth']);
lineChartData.all.VDSLData.push(data[keys[i]]['vdsl']);
lineChartData.all.ADSLData.push(data[keys[i]]['adsl']);
But for looping over object's keys is easier to use this:
for (let key in data) {
lineChartData.all.FTTHData.push(data[key]['ftth']);
lineChartData.all.VDSLData.push(data[key]['vdsl']);
lineChartData.all.ADSLData.push(data[key]['adsl']);
The alternative syntax will feed you keys and in my opinion is easier to read.
var i = 0;
for (i = Object.keys(data).length - 1; i >= 0; i--) {
lineChartData.all.FTTHData.push(data[i]['ftth']);
lineChartData.all.VDSLData.push(data[i]['vdsl']);
lineChartData.all.ADSLData.push(data[i]['adsl']);
this.lineChartIsLoaded = true;
Use v-if in vue component
<line-chart v-if="lineChartIsLoaded" :chart-data="lineChartData" :date-data="dateData" />
Set lineChartIsLoaded to false at default
const lineChartIsLoaded = false;
–
–
–
You can write dummy data in your data properties before real ones are loading
all: {
FTTHData: ["Loading..."],
VDSLData: ["Loading..."],
ADSLData: ["Loading..."],
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.