Search code examples
vue.jsmultidimensional-arrayvuejs2vue-componentvuex

How can I add new values to an array object of state using Vuex?


My code like this :

<template>
    ...

    ...
</template>

<script>
export default {
    ...
    methods: {
        ...mapActions([
            'getDataDoctor',
            'getDataSchedule'
        ]),
        async visibilityChanged(isVisible, entry, item) {
            let param = {
                hospitalId: item.hospital_id,
                doctorId: item.doctor_id
            }
            await this.getDataSchedule(param)
            let data = this.dataDoctor
            for (let key in data) {
                this.$set(data[key].find(e => e.doctor_id === item.doctor_id && e.hospital_id === item.hospital_id), 'schedule', this.dataSchedule.schedule)
            }
        }
    },
    computed: { 
        ...mapState({
            dataDoctor: state => state.dataStore.dataDoctor,
            dataSchedule: state => state.dataStore.dataSchedule
        }),
    },
}
</script>

If I console.log(this.dataDoctor), the result like this :

enter image description here

Or you can see the this.dataDoctor this : https://pastebin.com/yGjsTBjX

this.dataDoctor is state from vuex store. I want to add new value there. The name is schedule

I do like that. But there exist error like this :

Cannot set reactive property on undefined, null, or primitive value: undefined

Uncaught (in promise) TypeError: Cannot use 'in' operator to search for 'schedule' in undefined

How can I solve this problem?


Solution

  • This bit looks wrong:

    for (let key in data) {
        this.$set(data[key].find(e => e.doctor_id === item.doctor_id && e.hospital_id === item.hospital_id), 'schedule', this.dataSchedule.schedule)
    }
    

    From the sample data you posted this will only find something for (at most) one value of key. For the other values of key the find will return undefined and the $set will fail.

    Try this:

    for (const key in data) {
      const entry = data[key].find(e => e.doctor_id === item.doctor_id && e.hospital_id === item.hospital_id)
    
      console.log(`key is ${key}:`, entry)
    
      if (entry) {
        this.$set(entry, 'schedule', this.dataSchedule.schedule)
      }
    }
    

    Of course it is also possible that none of the entries will match. The console logging I've included should help you to identify that scenario too.

    I should add that it is usually regarded as best practice to mutate store state within a store mutation rather than directly inside a component.