Skip to content
Advertisement

Vuex | Be able to update outside of a mutation

I am trying to update a state of a action which is controlled through Vuex. I know initially, I am unable to update the state of the action without doing it directly through a mutation. However, I didn’t really want to do that as I am trying to use it in a callback. So I attempted to clone this array of actions and then use this variable. However, this seems to produce the same error:

do not mutate vuex store state outside mutation handlers

Whenever my modal is changing I am adding a watcher, which checks if the modal has actions and if it does “clone” it to a local variable using a for loop.

@Watch('modal')
onModalChanged(modal: ModalData) {
    if (modal && modal.actions) {
        for (let i = 0; i < modal.actions.length; i++) {
            this.actions[i] = modal.actions[i];
        }
    }
}

Then I have a v-for loop within my template which is looping through the actions local variable and performing a @click.

The action is setup like the following when constructing the modal:

modalStore.show({
  ...,
  actions: [
    {
      text: 'Save',
      theme: 'positive',
      click: (action: Action) => {
    
      }
    }
  ]
});

Within the click method I want to be able to set the loading status of the action i.e.

click: (action: Action) => {
  action.loading = true;
}

This way, I can determine if the button should show a loading state, but this is where the problem lies as I get the do not mutate vuex store.

Do I have to go through a state, as this is with modals there could be multiple which would mean I would have to make a method like the following:

updateButtonState(modal: ModalData, actionIndex: number, loading: boolean) {
  modal.actions[actionIndex].loading = true;
}

But at the point of creating the modal, I don’t have a reference to pass in for the modal.

Is there a workaround or a better way to approach this?

The minimal method of action.loading = true would be ideal although I do know this might not be achievable.

Advertisement

Answer

Firstly you should now that objects (arrays are also objects) are coping by link, not by value. So if you want to make a copy of an array you should make this this.copy = [...this.original] and then you will be able to change copy array without changing the original one from the store. But if you need to update it in the store as well, the only way is to make it with mutations. In this mutation you can pass an object with index of an array, value which you can save and so on.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement