0
votes

I would like to set the initial state of a data variable inside a component from the vuex store.

However, I do the api call to update the vuex store from the component to ensure that the data is up to date.

So in my component I have the following which initiates an update

    created: function () {
        uibuilder.send('getSchedules')
    },

the message is returned from my API and this is picked up in my main index.js:

this.$store.commit('schedules/SAVE_SCHEDULES', newVal.payload);

and the update happens by a mutation in the store.js

    SAVE_SCHEDULES(state, schedules) {
        state.schedules = schedules;
    },

The data that is pulled in is to be used to populate the initial value of a textbox in the component. I thought that I could set a computed property to access the object in the vuex state

    computed: {
        schedule() {
            return this.$store.getters['schedules/getScheduleByName'](this.picked);
        },
    },

and then set the data object with the value from the computed object.

    data() {
        return {
            picked: 'shd-1',
            tag: this.schedule.tag
        }
    },

I can then use v-model to keep track of changes to the value of the textbox.

<input type="text" id="shd-tag" class="mb-2" v-model="tag">

However, no matter where I put the API call in the lifecycle of the component I get an undefined value error:

Error in data(): "TypeError: Cannot read property 'tag' of undefined"

It seems that the vuex store is not updated before I try to access it in the data definition. Does anyone have any ideas how I could achieve this please?

Thanks,

Martyn

1
this.picked, that you send as argument to your getter, what is? Is not in the component data() declaration, are you passing it as prop? - Raffobaffo
Apologies, I must have missed that out. I have now added it to the question. - MartynW
Most likely when the component mounts your http request isn't satisfied yet, so, because you are calling a property on an object not yet created you get the error. In general your logic does not make much sense to me, if you have a computed returning the whole object, you don't really need to add it in the data(), if you really want to access the tag property of the return object create a computed for that too, and inside it put a logic to check if the object is instantiated. - Raffobaffo

1 Answers

1
votes

As for comments, declaring a reactive string, coming from an object that get instantiated by an http call is not the best solution. When your component is mounted, the http request most probably didn't complete yet.

To simplify, you can change your computed to:

computed: {
    schedule() {
        return this.$store.getters['schedules/getScheduleByName'](this.picked);
    },
    //this will return the tag if present, or an empty string
    tag() {
      return (this.schedule.tag) ? this.schedule.tag : "";
    }
},

and remove tag from data()

    return {
        picked: 'shd-1',
         //now instead of the tag declared here,
         //you can call your computed property tag in the same exact way
    }