Shawn Wildermuth

Author, Teacher, and Filmmaker
.NET Foundation Board Member

Changing Nested State in Vuex


I've been updating the Atlanta Code Camp website to improve our administration workflow. With the Call for Speakers coming up soon, I wanted to make sure we had a good way of picking only the best talks.

One of the things I've done is move it to a Single App with Vuex at the center of it. But I ran into an oddity with Vuex that I thought I'd share.

Much of the work I do in Vuex has to do with adding, updating and removing objects from the state. That works exactly the way I would expect. For example, I have a lot of mutations that looks like this:

export default {
  setCamps(state, camps) { state.camps = camps },
  setCurrentCamp(state, camp) { state.currentCamp = camp; },
  setBusy(state) { state.isBusy = true; },
  clearBusy(state) { state.isBusy = false; }
};

These are simple mutations, but I also needed to change some flags on objects. This is where it got confusing. When I did what I thought was obvious, it didn't reflect my changes (e.g. didn't react):

  setTalkApproved(state, talk, value) {
    talk.approved = value;
  }

Even though I wasn't setting the value using the state (only changing a value on the property of an object on the state, in this case inside a collection), it didn't work. It didn't work for a couple of reasons. First the value was always false (because nothing was passed for the 'value'). Secondly, Vuex wasn't aware what object I was changing.

Digging in I saw the error of my ways:

  setTalkApproved(state, {talk, value }) {
    talk.approved = value;
  },

The change is subtle, but by passing in an object that contained both the object to be changed and the value, Vuex knew to make the change in a stateful way. This can work for more than just two objects, but I wanted to share how I was able to change nested state. Hope it helps you when this happens to you.