1
votes

In my component I have:

currentItem.recipe

currentItem is a state in vuex initiated as object:

currentItem: {} 

In the same component I import it with mapState:

...mapState('ItemStore', [
      'currentItem'
])

When I add a recipe for it, this mutation gets called:

ADD_ITEM_RECIPE: (state, recipe) => {
   state.currentItem.recipe = recipe
}

recipe is response from server to a post request to create a new recipe.

In my component I have some v-if="currentItem.recipe", which is false at the beginning as currentItem has no recipe

The mutation get executed, in devtools I can see recipe being added to currentItem. But component does not update. The v-if does not change to true. In devtools, if I commit the mutation manually it works as expected.

So I tried to change the mutation to:

state.currentItem.recipe = Object.assign({}, state.currentItem.recipe, recipe)

but the problerm is still there.

Why is this happening and how can I solve it?

2

2 Answers

3
votes

Try to rewrite the entire object:

ADD_ITEM_RECIPE: (state, recipe) => {
   state.currentItem = {...state.currentItem, recipe: recipe}
}
1
votes

You're adding a new key to an existing object and as such reactivity doesn't work on that.

@HansFelixRamos answer is right, but you have also other alternatives.

  1. You're Object.assign is close, but no cigar. You need to update the entire object.

    state.currentItem= Object.assign({}, state.currentItem, {recipe})

    This will add recipe to a new object, while shallow copying all the information from state.currentItem.

  2. Another approach is to declare recipe on the state object from the start.

state: {
 currentItem: {
  //other properties 
  recipe: false // or null, or undefined
 }
}

I think the second approach is more suitable, especially for longer path object. If you declare default values for all keys you don't need to write defensive code like this const val = obj && obj.path1 && obj.path1.path2 && obj.path1.path2.path3 to access deeply nested properties.