Home » vue » Why an addition of a key does not trigger a watched variable? [duplicate]

Why an addition of a key does not trigger a watched variable? [duplicate]

Posted by: admin November 26, 2021 Leave a comment


I have an Object allevents asynchronously updated with keys and values. Whenever allevents is modified I would like to trigger a recalculation function.

To do so, I use the following Vue structure (in a component, all irrelevant elements removed):

export default {
        data: function () {
            return {
                allevents: {},
                events: []
        methods: {
            mqttMessage(topic, message) {
                const cal = topic.split('/').pop()
                this.allevents[cal] = JSON.parse(message).filter(x => true)
                // following the update above, I was expecting that since 
                // allevents is watched below, the function would trigger
                // as a workaround, I added this line below which fixes the issue
                // but I still would like to understand the lack of trigger
            // the function ssupposed to be triggred after a chnage, below
            computeEvents() {
                this.events = []
                Object.values(this.allevents).forEach(cal => cal.forEach(e => this.events.push(e)))
        watch: {
            // whenever allevents change, run computeEvents() <-- this does not happen
            allevents() { 
                console.log("events compute triggered")
        mounted() {

Even though allevents is modified and is watched, computeEvents() is not started. Why?


It appears you are victim of a Reactivity/Change Detection Caveat.

Instead of:

this.allevents[cal] = JSON.parse(message).filter(x => true)


Vue.set(this.allevents, cal, JSON.parse(message).filter(x => true))


this.$set(this.allevents, cal, JSON.parse(message).filter(x => true))

Relevant excerpt from the docs:

Change Detection Caveats

Due to the limitations of modern JavaScript (and the abandonment of
Object.observe), Vue cannot detect property addition or
. Since Vue performs the getter/setter conversion process
during instance initialization, a property must be present in the
data object in order for Vue to convert it and make it reactive. For

var vm = new Vue({
  data: {
    a: 1
// `vm.a` is now reactive
vm.b = 2
// `vm.b` is NOT reactive

Vue does not allow dynamically adding new root-level reactive
properties to an already created instance. However, it’s possible to
add reactive properties to a nested object using the Vue.set(object,
key, value)

Vue.set(vm.someObject, 'b', 2)

You can also use the vm.$set instance method, which is an alias to
the global Vue.set:

this.$set(this.someObject, 'b', 2)