Why is my false conditional element fickering while route is loading?

43 views Asked by At

Background: I have a page that displays a different div depending on Axios response. If the Axios Get request brings back response that does not populate data array myExpense[], it shows the div with the alert-warning class. Other wise if the response does populate the array it shows the div with the alert-succes class. Here is the code:

<template>
  <div class="profilePage">
    <div class="container">

      <div class="row">

        <div class="col" v-if="Array.isArray(myExpense)
       && myExpense == 0"><!--Warning div-->
          <p class="alert alert-warning">You do not have a budget at the moment</p>
          <router-link to="/budgetform" tag="button" class="btn btn-primary mt-5">Create Budget</router-link>
        </div>

        <div v-else class="col-md-12 alert alert-success"><!--Success div-->
          <p class="yourBalance">
            Your monthly balance
            <br />
            <span>${{myExpense[0].earnings}}</span>
          </p>
          <router-link to="/mybudget" tag="button" class="btn btn-primary mt-5">My budget</router-link>
        </div>
      </div>
      <div class="row">
        <div class="col-md-12">
          <a href="http://localhost:3000/auth/logout" class="btn btn-primary">Logout</a>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from "axios";
export default {
  name: "userProfile",
  data() {
    return {
      myExpense: [],//This array to be populated by axios response
         };
  },
  methods: {},
  created() {
    axios
      .get("http://localhost:3000/budget", {
        headers: { "Content-Type": "application/json" },
        withCredentials: true
      })
      .then(res => {
        if (res.data.name == undefined) {
          this.$router.push("/");
        }
        this.profile = res.data;
        this.myExpense = res.data.budget;
      });
  }
};
</script>

Problem:

Whenever this page is rendered, the false div flickers before displaying the right div based on the condition. Also, sometimes it shows white space as well.

I tried adding v-cloak but that doesn't seem to be the problem.

Thanks in advance for the help

1

There are 1 answers

0
Eddie Weldon On BEST ANSWER

I was able to find out the problem. The get request was not retrieving the data as fast as it took to render the page. So I had to use beforeRouteEnter to the retrieve the data before the component renders

Like so:

beforeRouteEnter(to, from, next) {
    axios
      .get("http://localhost:3000/budget", {
        headers: { "Content-Type": "application/json" },
        withCredentials: true
      })
      .then(res => {
        next(vm => {
          vm.userName = res.data.name;
          vm.myExpenses = res.data.budget[0].expenses;
          vm.earnings = res.data.budget[0].earnings;
        });
      })
      .catch(err => {
        next(vm => {
          vm.err = err;
        });
      });
  }