Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which VueJS lifecycle hook must Asynchronous HTTP requests be called in?

I'd like to know how before I render a page, I want to send an async GET request to my server to retrieve data and populate the properties in data. I heard the best way to do this is to call the function that sends this request in one of the three lifecycle hooks Vue js offers that operate before the DOM is rendered. The three are beforeCreate(), created(), beforeMount(). Which one must this request be called in ideally? And why?

like image 292
Baalateja Kataru Avatar asked Mar 30 '18 15:03

Baalateja Kataru


People also ask

What are lifecycle hooks in Vue JS?

Lifecycle hooks are a window into how the library you are using works behind the scenes. Lifecycle hooks allow you to know when your component is created, added to the DOM, updated, or destroyed. This article will introduce you to the creation, mounting, updating, and destruction hooks in Vue.

What are lifecycle hooks in Vue 3?

Each Vue component instance goes through a series of initialization steps when it's created - for example, it needs to set up data observation, compile the template, mount the instance to the DOM, and update the DOM when data changes.

What is onMounted in Vue JS?

[Vue warn]: onMounted is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.


2 Answers

TL;DR in the general (and safe) case, use created().

Vue's initialization code is executed synchronously.

Technically, any ASYNChronous code you run in beforeCreate(), created(), beforeMount() will only respond after all of those hooks finish. See demo:

new Vue({    el: '#app',    beforeCreate() {      setTimeout(() => { console.log('fastest asynchronous code ever') }, 0);      console.log('beforeCreate hook done');    },    created() {      console.log('created hook done');    },    beforeMount() {      console.log('beforeMount hook done');    },    mounted() {      console.log('mounted hook done');    }  })
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>  <div id="app">    Check the console.  </div>

In other words, if you make an Ajax call in beforeCreate(), no matter how fast the API responds, the response will only be processed way later, way after the created() has been executed.


What should guide your decision, then?

  • Need just to trigger a call as soon as possible?
    • Use beforeCreate()
    • Why?
      • It runs sooner than any of those hooks, but...
  • Need to read from or modify data right away?
    • Use created()
    • Why?
      • State is only initialized between beforeCreate() and created(), so if you assign some data before created(), it would be lost.
  • Need anything that is generated after created()?
    • Use beforeMount()
    • Why?
      • I don't know anything that isn't available at created() and is available at beforeMount() other than the compiled this.$options.render render function (see source as well), so this case must really be a rare situation.
like image 178
acdcjunior Avatar answered Sep 25 '22 07:09

acdcjunior


The vue-router docs have some advice for patterns to use when retrieving data from a server that is required for component render (see bottom for link).

To determine where to perform the GET request, they first ask if you want to navigate to the route before async GET request is initiated or after

If you want to fetch the data then navigate to the route (before navigation) then the docs suggest performing the async request in the beforeRouteEnter() guard on the incoming component making sure to call next() in beforeRouteEnter() once the async data request has been fulfilled. If you choose this pattern you will want to display some sort of loading indicator as the navigation to the route/rendering of the component will not occur until the data has been fetched.

If you want to navigate to the route then initiate the request (after navigation) then the docs suggest performing the request in the created() hook and using v-if to conditionally show either that the component is loading, an error has occurred, or the view once the data has arrived.

Highly recommend checking out the docs, they have code examples and its well written. https://router.vuejs.org/guide/advanced/data-fetching.html#fetching-before-navigation

like image 29
Bobby Avatar answered Sep 22 '22 07:09

Bobby