0

I seem to be having difficulty in updating a value in a component from the vuex store when it is updated. I have looked at this question (vue.js 2 how to watch store values from vuex) and followed the accepted answer but it is not working for me. Here goes with my explanation.

Data is received by my app and a mutation to the store happens (I have verified that this is working using vuejs devtools). Here is the relevant code:

        uibuilder.onChange('msg', function(newVal){
            //console.info('[indexjs:uibuilder.onChange] msg received from Node-RED server:', newVal)
            switch(newVal.topic) {
                // Process new data from a sensor
                default:
                    var parts = newVal.topic.split("/")
                    for (const [key, value] of Object.entries(newVal.payload)) {
                        if (!(key === "heater" || key === "battery")){ 
                            var device = { id: parts[2], name: parts[3] + '/' + parts[4], function: key, value: value }
                            this.$store.commit('rooms/UPDATE_VALUE', device)
                        }
                    }

this triggers the mutation in the store/rooms.js module:

mutations = {
    UPDATE_VALUE(state, payload){ // Updates the value of a device in room
        let device = state.rooms.find(room => room.id === payload.id).devices
            .find(device => device.name === payload.name && device.function === payload.function)
        device.value = parseFloat(payload.value)
    },
}

and as I say this is all happening. I have a component that is displaying the device value (on a gauge, but I have removed that for now and just display the value on the page to simplify).

<template>
    <b-card no-body class="bg-secondary text-light">
        <b-card-body class="bg-secondary m-0 pt-0 pb-0">
            <button @click="test">Test</button>
            {{ deviceValue }}
        </b-card-body>
    </b-card>
</template>

<script>
module.exports = {
    props: {
        'gDevice': {type: Object},
        'gRoom': {type: String},
    },
    data: function () {
        return {

        }
    },
    computed: {
        deviceValue() {
            return this.$store.getters['rooms/getDeviceValue'](this.gRoom, this.gDevice.name);
        },
    },

    methods: {
        test: function(event){
            console.log(this.deviceValue)
        }
    },

    created(){
        console.log(this.deviceValue) // Check a value is being returned (it is)
    },

    mounted: function () {

    },

    watch: {
        deviceValue (newval, oldval) {
            console.log(newval)
        },
    }
}
</script>

When a new value comes into the app the store is definitely updated but it is not triggering anything to happen in my component. I added a button to test whether the computed value is changing - it is not! I guess this explains why the watch event is not being fired. I just don't understand why the computed value is not updating even though the value in the store has definitely changed. Hopefully someone can see my error.

Here is the getter in the store:

getters = {
    getDeviceValue: (state) => (roomname, devicename) => { // returns the value from a device in a room
        return state.rooms.find(room => room.name === roomname).devices.find(dev => dev.name === devicename).value;
    },
}

!!UPDATE!! I just discovered that the mutation to the value is not being committed. If I use the devtools and press the "Commit all" then everything updates as expected. But if I reload the app then I have to do this again. I have no clue how to fix this???

Thanks Martyn

MartynW
  • 641
  • 2
  • 7
  • 23

0 Answers0