4

Recently I design web that user was separated into "user"/"admin" two roles to login.
Different role would login same page but see the different buttons and functions.

MainPage.vue is the container so I call ajax "/init" to get user info and then commit to Vuex store.
Then Content.vue is the child page inside MainPage.vue. It would show different buttons by $store.state.user message.

However, I would like to call different api in mounted stage inside Content.vue according to user's role.
But the role would not be prepared which is commited by ajax called "/init" at this stage.

The overall flow is
// MainContent.vue

beforeCreate: async function () {
            await axios.post('/init').then(response => {
                if(response && response.data && response.data.data){
                    this.$store.commit("login", response.data.data)   
                }
            })
        }

// Content.vue

mounted: async function() {
    try {
      console.log(this.$store, this.$store.state.user, this.$store.getters.isAdmin)
      // no value here 
}

I have check the vue component lifecycle and saw beforeCreate of parent would be called before mounted of child.
Would lifecycle methods call in order even they are async function?
How should I solve this problem?

Thanks

2 Answers 2

4

You could delay the initialization of the Content component until the user state becomes available in Vuex by attaching a v-if directive to the Content component. Just make sure to initialize user with null in the Vuex state.

<!-- MainPage.vue -->
<template>
  <Content v-if="$store.state.user" />
</template>

Now this.$store.state.user and everything that depend on it should be available from Content component's mounted lifecycle hook.

Sign up to request clarification or add additional context in comments.

Comments

1

Your component lifecycle will not be a dependable way to handle this case since you're using an async call to fetch the user data. I would suggest displaying a loading state overlay and using mapGetters to access the store. This will provide a reactive mechanism for you to know when the user data is available. Below is a general idea for a single file component:

computed: {
    ...mapGetters({
        getLoggedInUser: 'GET_LOGGED_IN_USER',
        getIsUserAdmin: 'GET_IS_USER_ADMIN',
    })
}

....

<template>
    <content-overlay v-if="!getLoggedInUser">
         Loading...
    </content-overlay>

    ....
    <button v-if="getIsUserAdmin">Admin Button</button>
    <button v-if="!getIsUserAdmin">Regular User Button</button>

</template>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.