简体   繁体   中英

VueX/VueJs : Execute code in component after async process

I'm trying to display a toast when a async request is finished. I've implemented this process:

  1. Single File Component calls updateUserProfile() actions in my VueX store
  2. updateUserProfile() actions makes a outgoing HTTP request on a server using Axios
  3. When succeeded, I use a mutation to update the user profile in my store and i would like to show a toast from my single file component.

Problem is that the response object is always undefined in my component. Where is my mistake ?

Error :

profile.vue?a62a:328 Uncaught (in promise) TypeError: Cannot read property 'data' of undefined at eval (profile.vue?a62a:328)

Store:

/*
  * Action used to fetch user data from backend
  */
updateUserProfile ({commit, state}, userData) {

  // Inform VueX that we are currently loading something. Loading spinner will be displayed.
  commit('SET_IS_LOADING', true);

  axiosBackend.put('/user/profile', userData, { headers: { Authorization: state.authString } } ).then(res => {

    console.log('PUT /user/profile', res);

    // Set user Data in VueX Auth store
    commit('SET_USER_DATA', {
      user: res.data.data
    });

    // Reset is Loading
    commit('SET_IS_LOADING', false);

    return res.data;

  })
  .catch(error => {
    // Reset isLoading
    commit('SET_IS_LOADING', false);
  });

}

Component:

methods: {
    // mix the getters into computed with object spread operator
    ...mapActions([
        'updateUserProfile'
    ]),
    // Function called when user click on the "Save changes" btn
    onSubmit () {
        console.log('Component(Profile)::onSaveChanges() - called');
        const userData = {
            firstName: this.firstname,
        }
        this.updateUserProfile(userData).then( (response) => {
            console.log('COMPONENT', response);
            if (response.data.status === 200) {
                toastr.success("Your profile has been successfully updated.");
            }
        });
    }
}

Well,

It would be better idea if You trigger the toast from the Vuex store itself as mentioned below.

callAddToCart: ({ commit }, payload) => {
    axiosBackend.put('/user/profile', userData, { headers: { Authorization: 
       state.authString }}).then(response => {
       commit("setLoading", false, { root: true });
       payload.cartKey = response.key;
       commit("setNotification", {
           type: 'success',
           title: `title`,
       });
       commit("ADD_TO_CART", payload);
   });
},

and inside mutation you can have a general notification toast and you can pass type, message and title as below.

setNotification(state, {type, message, title}) {
    state.flash = { 
       type,
       title, 
       message
    }
}

NOTE: Do not forget to load toast element at the root level in order to display in the UI.

Here is working example

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM