Pause and check for the completion of data loading in mapstate

I have a stored userProfile in the Vuex state in order to access it throughout my project. However, when I try to use it in the created() hook, the profile is not loaded yet during the initial page load. Although the object exists, it does not contain any data at that moment. Interestingly, accessing it later on, such as by clicking a button, works perfectly fine. Is there a way to wait for the data to finish loading?

This is how the userProfile is set in Vuex:

mutations: {
    setUserProfile(state, val){
      state.userProfile = val
    }
},
actions: {
    async fetchUserProfile({ commit }, user) {
      // fetch user profile
      const userProfile = await fb.teachersCollection.doc(user.uid).get()
  
      // set user profile in state
      commit('setUserProfile', userProfile.data())
    },
}

Below is where I am trying to access it:

<template>
<div>
  <h1>Test</h1>
  {{userProfile.firstname}}
  {{institute}}
</div>
</template>


<script>
import {mapState} from 'vuex';

export default {
  data() {
    return {
      institute: "",
    }
  },
  computed: {
      ...mapState(['userProfile']),
  },
  created(){
    this.getInstitute();
  },

  methods: {
    async getInstitute() {
      console.log(this.userProfile); //is here still empty at initial page load

      const institueDoc = await this.userProfile.institute.get();
      if (institueDoc.exists) {
        this.institute = institueDoc.name;
      } else {
        console.log('dosnt exists') 
      }
      
    }
  }
}
</script>

Upon logging in the console, I discovered that the issue lies in the sequence of code execution. First, the method getInstitute runs, followed by the action, and then the mutation. I attempted to introduce a loaded parameter and experimented with await to resolve this problem, but nothing has provided a solution.

Answer №1

Even if you decide to make the created or mounted methods asynchronous, it will not cause any delay in rendering your component. The delay will only affect the code execution after an await statement.

If you wish to hold off rendering a section (or all) of your template until the userProfile object has a specific property like an id, you can easily achieve this using v-if

<template v-if="userProfile.id">
  <!-- Your regular HTML content here... -->
</template>
<template v-else>
   Loading user profile...
</template>

To execute code whenever there is a change in the userProfile object, you can set up a watcher on one of its inner properties. Here's how you can do it:

export default {
  data: () => ({
    institute: ''
  }),
  computed: {
    ...mapState(['userProfile']),
  },
  watch: {
    'userProfile.institute': {
      async handler(institute) {
        if (institute) {
          const { name } = await institute.get();
          if (name) {
            this.institute = name;
          }
        } 
      },
      immediate: true
    }
  }
}

A little side note: In Vue 3, there is a feature called Suspense that addresses this pattern. It offers great flexibility by allowing the rendering condition to be completely independent from the parent component. Each suspensible child can declare whether it is currently loading or done loading, and once all children are ready, the main template is rendered.
Additionally, if new children are dynamically added, the suspense will switch back to a fallback (loading) template until the newly added children are loaded. All this functionality comes out of the box, with the only requirement being to make sure the children have asynchronous mounted methods.
In essence, Vue 3 provides what was anticipated in Vue 2.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Display a loading spinner until all child components within a Page have finished rendering in Nativescript

I need to display an activity indicator when transitioning from one page to another, but the destination page has multiple components that take time to load. I am looking for a way to detect when all child components are loaded so that I can update my vari ...

JQuery enthusiast seeks cheerful clicker for callback upon event binding

Incorporating a complex functionality into a click event is proving to be challenging $(someSelector)).bind('click', someFunction(a,b,c)); function somefunction(a,b,c) { return function() { // dive into complexity $(anotherS ...

Adjust the number of columns based on the minimum screen resolution using columnizer

Currently, I am utilizing the columnizer jQuery plugin to divide my content into columns on a responsive website with a fluid width container. I have implemented different JavaScript functions based on the minimum screen resolutions, similar to CSS media q ...

Switching out one block of HTML with another in JavaScript is a powerful way to dynamically update

I am working on creating a feature on a webpage where clicking a button will change the HTML code inside a specific div. Essentially, I want to be able to update the content of a div by simply clicking a link. Here are two different sets of HTML code: Co ...

What is the best way to fix the Syntax error that reads "Unexpected token (1:13)"?

I can't seem to figure out why my code keeps showing errors in the browser. I'm still new to coding and learning slowly, with help from knowledgeable individuals on stackoverflow :) Card 1.jsx Syntax error:() Unexpected token (1:13) > 1 | i ...

Using Vue.js: Sending a Data Object to the Store via an Action

I am looking for a way to send a data object to my Vue store using an action. This is my current approach: <button type="button" name="button" class="btn btn-primary" @click="addToCart(row)">Add to cart</button> ...mapActions(["addToCart"]) ...

Develop a custom class for importing pipes in Angular 4

Currently, I am working on creating a pipe that will replace specific keywords with the correct strings. To keep this pipe well-structured, I have decided to store my keywords and strings in another file. Below is the code snippet for reference: import { ...

Created JSON object providing the number as a string value

I am currently facing an issue with a Vue method where it generates a JSON object from user input values before making an axios put request. The problem I'm encountering is that the JSON object generated converts numbers into strings, causing issues w ...

Tips for sending an input file to an input file multiple times

As a developer, I am facing a challenge with a file input on my webpage. The client can add an image using this input, which then creates an img element through the DOM. However, I have only one file input and need to send multiple images to a file.php i ...

Looking to retrieve a cookie within Vue Router in Vue 3? Utilize the following approach within your router's `index.js

Scenario: Developing a Vue3 app with express as the API backend. Express utilizes express-sessions to create a server-side session that is transmitted to the browser and received in subsequent requests. I am in the process of implementing a route guard to ...

Send form based on the outcome of the ajax request

I have developed a form that triggers an ajax request upon submission to check the validity of the data. My goal is to automatically submit the form if the ajax response confirms the data is valid, and prevent the form submission if the data is invalid. $ ...

Using Javascript to add hovering effects that demonstrate sophistication and style

I have a question : Here is the HTML code snippet: <div class="a b"> <span class="one">Success ONE</span> <span class="two">ONE</span> </div> <div class="a b"> <span class="one">Success TWO< ...

Execute the javascript function asynchronously

I need to call the constGrid(arg1) function 3 times to set up an extjs grid when my form loads. There are other fields on my page as well. I want to ensure that the page does not hang or wait for the method to complete. onLoad(function() { for (var i= ...

Why is a dispatch call in React-Redux being executed before another?

My Pokedex is functioning properly, but I have encountered an issue with React-Redux Dev Tools: https://i.sstatic.net/F0Ifh.png The function "getPokemonsInfo" is being called before "getPokemonsUrls", however, "getPokemonsInfo" should only be triggered w ...

Transforming color images into black and white using JavaScript

     I have implemented this code to convert colored images to grayscale. function applyGrayscaleEffect() {         var imageData = contextSrc.getImageData(0, 0, width, height);         var data = imageData.data;         var p1 = 0.99;   ...

What is the reason behind the browser permitting cross-origin POST requests but not PUT requests?

Let's consider a straightforward example of utilizing the XMLHttpRequest. The following code snippet functions correctly (you can verify in the network tab or by navigating your browser to http://requestb.in/yckncpyc) despite displaying a warning in ...

Transferring information using express

Currently, my Express server is up and running and it's set to send an HTML file from the public folder of my project. The issue arises when I try to initiate a request from a client script linked in this HTML file to send data back to the server. Des ...

Adjust the class based on the model's value in AngularJS

items = {'apple', 'banana', 'lemon', 'cat', 'dog', 'monkey', 'tom', 'john', 'baby'} html <div class="variable" ng-repeat="item in items">{{item}} </div> ...

Ways to retrieve information from a specific key

I'm currently facing a challenge accessing specific data objects that are referenced by keys. In this particular scenario, the "applicant" data is nested within an Event object. My goal is to extract this data and create a new object from it. While I ...

Is it possible to obtain the impending exception handling protocol in advance?

In upcoming scenarios, unhandled promise rejections will lead to the termination of the Node.js process using a non-zero exit code. Despite encountering issues, my pipeline erroneously passed and deployed a faulty version that crashes upon launch. If Node ...