Leos Literak
Leos Literak

Reputation: 9474

Correct way of waiting for async result in Vue component

I wonder where to put in lifecycle waiting for the promise result. Runnable sample is there: https://codesandbox.io/s/focused-surf-migyw. I create a Promise in created() and wait for the result in async mounted(). Is this right and optimal usage of Vue component lifecycle?

PS I do not want to store the result as a mutation in the store because I can call this method multiple times. Therefore I return the Promise. It downloads user detail from a REST endpoint.

store.js

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  actions: {
    FETCH_PROFILE: async context => {
      const profile = { name: "Leos" };
      return new Promise(function(resolve, reject) {
        window.setTimeout(function() {
          resolve(profile);
        }, 2000);
      });
    }
  }
});

component.vue

<template>
  <div class="hello">
    <p>Name = {{this.userProfile.name}}</p>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    userProfile: null,
    profilePromise: null
  }),
  created() {
    this.profilePromise = this.$store.dispatch("FETCH_PROFILE");
    console.log(`my profile: ${this.userProfile}`);
  },
  async mounted() {
    const response = await this.profilePromise;
    console.log(response);
    this.userProfile = response;
  }
};
</script>

Upvotes: 1

Views: 7473

Answers (1)

Dan
Dan

Reputation: 63059

Unless you have some extraordinarily compelling reason to break this up into using both created and mounted, it would make more sense to do it all in created. You don't have to worry that this will postpone the mount because async calls are non-blocking. Use created rather than mounted, which is generally for DOM manipulation or DOM sensitive operations.

async created() {
  const response = await this.$store.dispatch("FETCH_PROFILE");
  this.userProfile = response;
}

Upvotes: 1

Related Questions