Add or set new data to object in Vuex store
Asked Answered
U

4

7

I'm trying to add or update an object in store with Vuex.

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    userData: {}
  },
  mutations: {
    ADD_USER_DATA: (state, data) => {
      state.userData.push(data)
    }
  }
})

This returns state.userData.push is not a function.

And in the components:

<template>
  <div>
    <input type="date" v-model="inputData.date1">
    <input type="date" v-model="inputData.date2">
    <input type="number" v-model="inputData.date3">
    <button @click="submitForm">Submit</button>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex'

export default {
  data () {
    return {
      inputData: {}
    }
  },

  computed: {
    ...mapState([
      'userData'
    ])
  },

  methods: {
    ...mapMutations([
      'ADD_USER_DATA'
    ]),
    submitForm () {
      this.ADD_USER_DATA(this.inputData)
    }
  }
}
</script>

Later on I want to update userData with a value from other component, so that it impacts both components. I would like to have a nice way of adding, replacing, concating the old array with a new array. I followed the example in this video.

(FYI: I'm currently learning Vue.js from scratch and couldn't figure out this Vuex's mutations, actions...)

Undeviating answered 15/12, 2018 at 14:30 Comment(6)
userData should be an array and it would be declared as : state: { userData: [] },Garretgarreth
@BoussadjraBrahim Reason I'm using an object is with an array I can push a multiple array to a userData but with an object you can't. If I change userData.push to Vue.set then it works but later on I can't add or replace an value.Undeviating
your userData contain the data of one user?Garretgarreth
@BoussadjraBrahim Yes.Undeviating
so you could do it simply like : state.userData=dataGarretgarreth
@BoussadjraBrahim Yes, but that will set the whole object with new values. I'm currently looking for replacing, concating method for this.Undeviating
B
4
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    // userData: {}
    userData: []
  },
  mutations: {
    ADD_USER_DATA: (state, data) => {
      state.userData.push(data)
    }
  }
})

You are trying to use a push method of Object. Object does not have a push method you should initiate userData value with Array [] or assign that data to the object

Baerl answered 15/12, 2018 at 15:4 Comment(1)
But with Array I can push multiple arrays to it. I'm simply trying to store an Object in state.Undeviating
S
4

if you need reactivity:

mutations: {
  ADD_USER_DATA: (state, data) => {
    Object.keys(data).forEach( key => {
      Vue.set(state.userData, key, data[key])
    })
  }
Secretin answered 25/4, 2019 at 16:39 Comment(0)
U
2

I've ended up using Object.assign method.

  mutations: {
    ADD_USER_DATA: (state, data) => {
      // state.userData.assign(data)
      state.userData = Object.assign({}, data)
    }
  }
Undeviating answered 15/12, 2018 at 15:54 Comment(1)
Hi, how would you do this in composition api as a function? And without overriding the data that is already there within state.userData?Arlenarlena
E
0

Try it

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    userData: {}
  },
  mutations: {
    ADD_USER_DATA: (state, data) => {
      state.userData.date1 = data.date1
      state.userData.date2 = data.date2
    }
  }
})
Eisegesis answered 11/5, 2021 at 6:2 Comment(2)
thanks for answering, please add some comments and note to make it more clearSlothful
Thank you for this code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please edit your answer to add some explanation, including the assumptions you’ve made.Fortuna

© 2022 - 2024 — McMap. All rights reserved.