1

I have a typical Vue data-table with a template section that displays an alert if no records are found. Problem is, that displays right away, even before my Axios method has a chance to go out and get records.

How can I prevent the flash of red warning message before the actual data loads?

<template>
  <div>
    <v-card>
      <v-card-title>
        <h1>Locations</h1>
      </v-card-title>

      <v-data-table :headers="headers" :items="locations" :search="search" :fixed-header="true" :loading="true" class="elevation-1">
        <template v-slot:items="location">
          <td>{{ location.item.id }}</td>
          <td>{{ location.item.company }}</td>
          <td>{{ location.item.category }}</td>
          <td>{{ location.item.name }}</td>
          <td>{{ location.item.city }}, {{ location.item.state }}</td>
        </template>
        <template v-slot:no-data>
          <v-alert :value="true" color="error" icon="warning">Sorry, no locations found.</v-alert>
        </template>
      </v-data-table>
    </v-card>
  </div>
</template>

<script>
import { HTTP } from "@/utils/http-common";

export default {
  name: 'LocationsList',
  data() {
    return {
      headers: [
        { text: "Id", value: "id" },
        { text: "Company", value: "company" },
        { text: "Category", value: "category" },
        { text: "Name", value: "name" },
        { text: "City, State", value: "city" },
      ],
      locations: [],
      errors: []
    };
  },
  created: function() {
    this.getAllLocations();
  },
  methods: {
    getAllLocations() {
      HTTP.get("locations")
        .then(response => {
          this.locations = response.data;
        })
        .catch(err => {
          this.errors.push(err);
        });
    },
  }
};
</script>
Connie DeCinko
  • 802
  • 2
  • 15
  • 32

1 Answers1

1
  1. Add a loading state to data, and set it to true
  2. Set the loading state when the call is finished (.finally promise)
  3. Set the v-if on in your template to show when it's not anymore loading

See code below.

<template>
  <div>
    <v-card>
      <v-card-title>
        <h1>Locations</h1>
      </v-card-title>

      <v-data-table :headers="headers" :items="locations" :search="search" :fixed-header="true" :loading="true" class="elevation-1">
        <template v-slot:items="location">
          <td>{{ location.item.id }}</td>
          <td>{{ location.item.company }}</td>
          <td>{{ location.item.category }}</td>
          <td>{{ location.item.name }}</td>
          <td>{{ location.item.city }}, {{ location.item.state }}</td>
        </template>
        <template v-slot:no-data>
          <v-alert v-if="!loading" :value="true" color="error" icon="warning">Sorry, no locations found.</v-alert>
        </template>
      </v-data-table>
    </v-card>
  </div>
</template>

<script>
import { HTTP } from "@/utils/http-common";

export default {
  name: 'LocationsList',
  data() {
    return {
      headers: [
        { text: "Id", value: "id" },
        { text: "Company", value: "company" },
        { text: "Category", value: "category" },
        { text: "Name", value: "name" },
        { text: "City, State", value: "city" },
      ],
      locations: [],
      errors: [],
      loading: true
    };
  },
  created: function() {
    this.getAllLocations();
  },
  methods: {
    getAllLocations() {
      HTTP.get("locations")
        .then(response => {
          this.locations = response.data;
        })
        .catch(err => {
          this.errors.push(err);
        })
        .finally(() => {
          this.loading = false;
        })
    },
  }
};
</script>
memic84
  • 129
  • 9