Matt B
Matt B

Reputation: 267

Vuex not updating state when using actions

Trying to get my head around VueX but struggling to get Axios to work with it. I have the following in my store.js file:

 state: {
    cards: [],
    currentPage: 1,
    lastPage: 2,
  },
  actions: {
    loadGradients(pageNumber) {
      if (axios == null) {
        return;
      }
      axios
        .get("/api/gradients?page=" + pageNumber + "&sort=" + "created_at")
        .then((res) => {
          if (res.status === 200) {
            state.cards = res.data.gradients.data;
            state.lastPage = res.data.gradients.last_page;
            state.currentPage = res.data.gradients.current_page;
          }
        })
        .catch((err) => {
          console.log(err);
        });
    },
  },

I'm calling it through the following function in my main app.js file:

  created() {
    this.loadGradients(1);
  },
  methods: {
    loadGradients: function (pageNumber) {
      this.$store.dispatch("loadGradients");
    },
  },

But when I run the page, the array in the store.js file isn't being updated it seems, even though the data is being returned correctly from the database. Not sure what I did wrong? If I have to use a combination of actions and mutation, how would I go about that please?

Upvotes: 1

Views: 1123

Answers (2)

Terry
Terry

Reputation: 66113

If you want to update the state, it should be done by committing a mutation inside your state. If you look at your loadGradients action, you will realize that state does not actually refer to the VueX state. It probably is undefined: check your console log.

A solution will be to create a mutation which you will commit in the action itself. First of all, when dispatching the action, you will need to include pageNumber in the second argument in the this.$store.dispatch method:

loadGradients: function(pageNumber) {
    this.$store.dispatch('loadGradients', pageNumber) ;
}

Then, in your action, access the pageNumber as the second argument. The first argument is a context object that can be unpacked:

actions: {
    loadGradients({ commit }, pageNumber) {
        if (axios == null) {
            return;
        }
        axios
            .get('/api/gradients?page=' + pageNumber +'&sort=' + 'created_at')
            .then(res => {
                if (res.status === 200) {
                    commit('updateState', {
                        cards: res.data.gradients.data,
                        lastPage: res.data.gradients.last_page,
                        currentPage: res.data.graduents.current_page,
                    });
                }
            })
            .catch(err => {
                console.log(err);
            });
    },
}

Create a mutation to handle setting the VueX store's state:

mutations: {
    updateState(state, { cards, lastPage, currentPage }) {
        state.cards = cards;
        state.lastPage = lastPage;
        state.currentPage = currentPage;
    }
},

Even though not advisable, you can actually still update the VueX store state within an action:

actions: {
    loadGradients({ state }, pageNumber) {
        if (axios == null) {
            return;
        }
        axios
            .get('/api/gradients?page=' + pageNumber +'&sort=' + 'created_at')
            .then(res => {
                if (res.status === 200) {
                    state.cards = res.data.gradients.data;
                    state.lastPage = res.data.gradients.last_page;
                    state.currentPage = res.data.graduents.current_page;
                }
            })
            .catch(err => {
                console.log(err);
            });
    },
}

Upvotes: 0

Rijosh
Rijosh

Reputation: 1544

Can you try assigning the response data to the store using mutations

mutations = {
  setCards:(state,data) => state.cards = data,
  setCurrentPage:(state,value) => state.currentPage = value,
  setLastPage:(state,value) => state.lastPage = value
}

And inside actions

        loadGradients({commit},pageNumber) {
            if (axios == null) {
                return;
            }
            axios
                .get('/api/gradients?page=' + pageNumber +'&sort=' + 'created_at')
                .then(res => {
                    if (res.status === 200) {
                       // calling the mutations
                        commit('setCards',res.data.gradients.data);
                        commit('setCurrentPage',res.data.gradients.current_page);
                        commit('setLastPage',res.data.gradients.last_page);
                    }
                })
                .catch(err => {
                    console.log(err);
                });
        },

Upvotes: 1

Related Questions