Vue.js - defer page rendering until data request finishes

Viewed 433

I have a page which displays data fetched from server with axios.

I want to defer the page rendering until the axios request finishes.

The reason for this is that I have a prerendered version of the page. So while the axios request is still running, I would like to display the prerendered data instead of a blank screen (to prevent CLS issues).

This is what I have currently:

export default {

  ....

  created() {
    this.fetchData().then((returnedData) => this.personData = returnedData);
  },

  data() {
    return {
      personData: {
        name: "",
      },
    };
  },

  methods: {
    async fetchData() {
      const response = await axios.get("api/persondata/");
      return await response.data;
    },
  },

  ...

}

So basically what I want to do is to make the axios request "synchronous", or to somehow make the create() function wait until the request finishes.

An ideal scenario would be to prevent the rendering all-together and just display the prerendered page, in case the axios request fails.

Any ideas on how to do this?

1 Answers

You can wrap in a v-if that waits for it to be loaded. A v-if instead of v-show to prevent errors from trying to read values that don't exist yet in your response object.

<template>
  <div v-if="!isLoading">
    Show your updated data here
  </div>
  <div v-else>
    Show your prendered data here
  </div>
</template>
export default {

  data() {
    return {
      personData: {
        name: "",
      },
      isLoading: true
    };
  },

  methods: {
    async fetchData() {
      const response = await axios.get("api/persondata/");
      return await response.data;
    },
  },
  async mounted(){
     this.personData = await this.fetchData()
     this.isLoading = false
  }
}

Wrap in try/catch to handle errors.

Having built some very large Vue projects, I have found that using this method, combined with components that render and format the data works best compared to using the router. Using the router hooks is nice for small applications, but quickly falls apart if you need to add any sort of page access tools or any other global routing features.

A typical pattern would be View -> read ID parameter -> pass to component that renders data -> component does axios to get data based on ID. If the route parameter changes (but the route does not) your component is still updated when the parameter changes.

Related