I had a table being populated by an axios get request, I tried implementing a Vuetify version of the table and was unsuccessful so I reverted what I did, and now I can not get any data to show in my table.
My Vue file...
<template>
<v-container fluid>
<div>
<table>
<thead>
<tr>
<th>ID</th>
<th>MACID</th>
<th>Start Time</th>
<th>Stop Time</th>
</tr>
</thead>
<tbody v-for="item in experimentList">
<tr>
<td>
<strong
><a
href="#"
@click="
SetCompareInfo(
item.macid,
item.start_timestamp,
item.end_timestamp
)
"
>{{ item.experiment_id }}</a
></strong
>
</td>
<td>{{ item.macid }}</td>
<td>{{ item.start_timestamp }}</td>
<td>{{ item.end_timestamp }}</td>
</tr>
</tbody>
</table>
</div>
</v-container>
</template>
<style></style>
<script lang="ts">
import Vue from "vue";
import axios from "axios";
import { Component, Prop, Watch } from "vue-property-decorator";
@Component({
components: {},
})
export default class ExperimentListFlow extends Vue {
$store: any;
experimentList: any;
created() {
this.GetExperiments();
console.log(this.experimentList);
}
GetExperiments() {
console.log("Inside GetExperiments");
var machine = this.$store.state.machineName;
console.log(machine);
var expList = [];
axios
.get(this.$store.state.baseUrl "/viruswarn/experiments")
.then(function (response) {
// handle success
for (var i = 0; i < response.data.experiment_details.length; i ) {
if (machine == response.data.experiment_details[i].macid) {
expList.push(response.data.experiment_details[i]);
console.log("pushed");
}
}
});
this.experimentList = expList;
}
SetCompareInfo(macid, start, stop) {
var data = {
macid: macid,
start: start,
stop: stop,
};
this.$store.commit("storeCompareInfo", data);
this.$router.push({ path: "/dashboard/live-plot/all/compare-plot" });
}
}
</script>
The response from the get request...
{
"experiment_details": [
{
"end_timestamp": 1658326622802,
"experiment_details": {
"setup": {
"condition": "NoVirus",
"media_addition": "Nebulization"
}
},
"experiment_id": "677",
"macid": "AA:BB:00:25:00:8B",
"start_timestamp": 1658326584000
},
{
"end_timestamp": 1658326622902,
"experiment_details": {
"setup": {
"condition": "NoVirus",
"media_addition": "Nebulization"
}
},
"experiment_id": "678",
"macid": "AA:BB:00:25:00:8B",
"start_timestamp": 1658326584100
},
{
"end_timestamp": 1659382175000,
"experiment_details": {
"setup": {
"condition": "NoVirus",
"media_addition": "Nebulization"
}
},
"experiment_id": "678",
"macid": "AA:BB:00:25:00:8B",
"start_timestamp": 1659382171000
},
{
"end_timestamp": 1659381258,
"experiment_details": {
"setup": {
"condition": "NoVirus",
"media_addition": "Nebulization"
}
},
"experiment_id": "678",
"macid": "AA:BB:00:25:00:8B",
"start_timestamp": 1659382258
}
]
}
I know the variable is being updated properly because console.log displays it correctly.
Also, if I modify the HTML only and then save the file, npm will reload the app in my browser and the data will show in the table. But it will not show when normally using the vue app.
And after modifying a little HTML the data shows up...
CodePudding user response:
As @EstusFlask pointed out, you are assigning expList
to experimentList
before the request gets back. At that point expList
is an empty array and experimentList
won't get the changes you perform to that empty array, after the request gets back.
In short, this code:
GetExperiments() {
console.log("Inside GetExperiments");
var machine = this.$store.state.machineName;
console.log(machine);
var expList = [];
axios
.get(this.$store.state.baseUrl "/viruswarn/experiments")
.then(function (response) {
// handle success
for (var i = 0; i < response.data.experiment_details.length; i ) {
if (machine == response.data.experiment_details[i].macid) {
expList.push(response.data.experiment_details[i]);
console.log("pushed");
}
}
// place the assignment here!
// This happens after the `expList` has been populated
});
// this gets executed just after request has been sent
// but before it has returned
this.experimentList = expList;
}
should be:
GetExperiments() {
console.log("Inside GetExperiments");
var machine = this.$store.state.machineName;
console.log(machine);
var expList = [];
axios
.get(this.$store.state.baseUrl "/viruswarn/experiments")
.then((response) => {
// handle success
for (var i = 0; i < response.data.experiment_details.length; i ) {
if (machine == response.data.experiment_details[i].macid) {
expList.push(response.data.experiment_details[i]);
console.log("pushed");
}
}
this.experimentList = expList;
});
}
... or, shorter version:
GetExperiments() {
axios
.get(this.$store.state.baseUrl "/viruswarn/experiments")
.then((response) => {
this.experimentList = response.data.experment_details.filter(
(detail) => detail.macid == this.$store.state.machineName
);
});
}
Side notes:
- the
then
callback has been changed to arrow function (otherwisethis.experiments
can't be accessed inside it) - the
v-for
should be on<tr>
, not on<tbody>
. - the
==
operator should likely be replaced by===
, on general principles. Using loose equality operator is a potential source of subtle bugs, which might cost you endless hours of debugging - you should ditch
vue-class-decorators
for either clean Options API syntax or Composition API syntax. There are multiple reasons to do it, but the main one is that by using decorators you severely diminish the pool of people who can help you when you ask questions.