Search code examples
vue.jsvue-componentvuexvuex-modulesvue-reactivity

Vuex not reactive


I tried to transition from directly using the bindings for my API in a View to putting all that logic in Vuex. I previously just used Vuex to store entities and included the list call as an action. In my view I for example issued the myAPI.create(...) call and then dispatched the list action. This worked fine.

After my transition, my View does not react to store updates:

store/modules/vehicles.js:

import vehiclesAPI from "@/api/vehicles";

const vehicles = {
  namespaced: true,

  state: {
    vehicles: []
  },

  mutations: {
    SET_VEHICLES(state, vehicles) {
      state.vehicles = vehicles;
    }
  },

  actions: {
    list({ commit }) {
      return new Promise((resolve, reject) => {
        vehiclesAPI
          .list()
          .then(response => {
            const vehicles = response.data;
            commit("SET_VEHICLES", vehicles);
            resolve(response);
          })
          .catch(e => {
            reject(e);
          });
      });
    },

    create({ commit }, vehicle) {
      return new Promise((resolve, reject) => {
        vehiclesAPI
          .create(vehicle)
          .then(response => {
            resolve(response);
          })
          .catch(e => {
            reject(e);
          });
      });
    }
  },

  getters: {
    vehicles: state => (state.vehicles ? state.vehicles : [])
  }
};

export default vehicles;

In my View I map my actions and getters. To create a vehicle I call

this.create(this.vehicle);
this.list();

Using the Vue DevTools for Chrome I noticed, that the mutation SET_VEHICLES from the list action does not contain the created vehicle. However, after issuing a reload, it works.

What am I doing wrong?

Interestingly it works, when calling this.list() in a setTimeout. But it does not work when I use the create() promises then or finally.


Solution

  • Is because actions are async by default, and you should use like this:

    this.create(this.vehicle)
        .then( () => this.list() )