Vuex state empty after reload



Inside a mutation I’m changing my state like:

try {
  const response = await axios.put('http://localhost:3000/api/mobile/v3/expense/vouchers/form_refresh', sendForm, {
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
      Authorization: 'Bearer ###'
    }
  });

  var obj = cloneDeep(response.data);
  var temp = cloneDeep(response.data.line_items_attributes.nested_form)

  temp = Object.keys(temp).map(key => {
    return {
      ...temp[key]
    }
  });

  obj.line_items_attributes.nested_form = cloneDeep(temp);

  state.form = cloneDeep(obj);
  console.log(state.form);
} catch (error) {
  ...
}

So the state shall hold an array with an object as the entry. Checking the state also shows the same. And it’s displayed on the view. When now reloading everything remains inside the state except of the object inside the array. It just shows an empty array inside the store:

line_items_attributes:
  attribute: "line_items_attributes"
  label: "Positionen"
  model_class: "expense_line_item"
  nested_form: []              // <---- Object is gone

Nested_form is a hahsmap delivered by the backend. I just turn it to an array. line_items_attribute is a property of the object stored in the state. EDIT: But it’s also not working without the transformation. The assigned state there just doesn’t get preserved.

store.js

const store = createStore({
    strict: false,
    plugins: [createPersistedState()],
    modules: {
        expense,
        invoice
    }
});

Calling the action/mutation like:

const updateOuter = (event, refreshable, propertyName) => {
   store.dispatch('expense/updateOuterValue', ({
      refresh: refreshable,
      propertyName: propertyName,
      value: event.target.checked ? 1 : 0
   }))
};

EDIT:

When changing a different value after calling the mutation the nested_form object is being preserved after the reload.

It seems to work if I call the mutation twice… Any idea how this could be?

Answer

The problem was the execution of axios inside the mutation. There must be no asynchronous calls inside a Vuex mutation. As suggested by @e200

You shouldn’t do async operations inside mutations, use actions instead.

So it’s more than just a best practice, rather a must do. Explianed here: mutations must be synchronous



Source: stackoverflow