ilrock
ilrock

Reputation: 593

How to make Vuex state update after axios call

I'm building a Nuxt app and I'm fetching some data from a node backend I've got running on my localhost.

I have a plugin getApps.js

export default ({ store }) => {
    store.dispatch('getApps')
}

That is calling a getApps action in my Vuex

actions: {
  getApps (context) {
    const {commit, state} = context
    commit('setLoading', true)

    let url = `apps?limit=${state.loadLimit}&page=${state.page}`

    if (state.query)
      url = `${url}/q=${state.query}`

    this.$axios.get(url)
      .then((res) => {
        const apps = res.data.apps
        console.log(apps)
        commit('addApps', apps)
        commit('setPage', state.page + 1)
        commit('setLoading', false)

      })
  }
  ...

The console.log here does indeed return the list of apps, however, after my addApps mutation

addApps (state, payload) {
  state.apps = payload
}

And this is the state definition

state: () => ({
  apps: [],
  query: '',
  loading: false,
  filters: [],
  loadLimit: 25,
  page: 1,
  showFilters: true,
  currentUser: null,
  showLoginModal: false,
  showCreateAppModal: false
})

The state doesn't get updated. As far as I could tell, this is due to the async nature of actions. I did also try to wrap the action around an async and prepend an await to the axios call, however, this did not work.

Why is this happening? How do I have to structure my code to make it work?

Upvotes: 3

Views: 1927

Answers (1)

nmfzone
nmfzone

Reputation: 2903

The problem is, you didn't aware with Promise. Your action call HTTP Request that is asynchronous, but you didn't await it.

And then, you should aware with Promise too in the Plugin section. The solution for your issue is very simple, you just need to await.

plugins/getApps.js

export default async ({ store }) => {
    await store.dispatch('getApps')
}

store/...

You can either make the function async, and await the axios, or you can return Promise from the action.

actions: {
  getApps (context) {
    ...
    return this.$axios.get(url)
      .then((res) => {
        const apps = res.data.apps

        commit('addApps', apps)
        ...
      })
  },
  ...
}

OR

actions: {
  async getApps (context) {
    ...
    await this.$axios.get(url)
      .then((res) => {
        const apps = res.data.apps

        commit('addApps', apps)
        ...
      })
  },
  ...
}

Upvotes: 4

Related Questions