1

I got a codesandbox that reproduces my problem: codesandbox example watcher not triggering.

I am working on a component that relies on an object with data that can be dynamically added to the object, so for example, in a seperate .js file, I am exporting the following object:

export default {
  defaultSection1: {
    displayName: 'Action',
  },
  defaultSection2: {
    displayName: 'Thriller',
  },
}

I import this object in my component.

I got a debouncer setup from Lodash so that when data changes, it only fires the watcher once after two seconds. The watcher IS triggered perfectly fine for the data that is already in the object (type in the input text box in my example, and the watcher is triggered). But when I dynamically add data to the object, the watcher is not triggered at all. Only when I change routes back and forth, the data is updated, but the watcher is not triggered. Why is this? What can I do so that the watcher is triggered when data is dynamically being added to an object.

methods: {
    fetchAndUpdateData(){
      console.log('Fetching data...')
    },
    addCustomSection(){
      //The watcher should be triggered when this function is called
      const newSectionId = Math.floor(Math.random() * 1000); 
      this.data[newSectionId] = {
         displayName: 'Custom'
      }
    }
  },
  computed: {
    dataWatcher() {
      return this.data;
    },
    updateData() {
      return debounce(this.fetchAndUpdateData, 2000);
    },
  },
  watch: {
    dataWatcher: {
      handler() {
        console.log('Watcher triggered')
        this.updateData();
      },
      deep: true,
    },
  },

Why is the watcher not triggered, when clearly the data is being changed?

Another thing I noticed that is quite strange, is that in Vue 3.0, the watcher IS triggered with exactly the same code.

Codesandbox in Vue 2.6.11, watcher not triggering.

Codesandbox in Vue 3.0, watcher IS triggered with exactly the same code.

1 Answer 1

3

In vue 2 there's reactivity issue when updating an item in an array or a nested field in an object, to solve this you've to use this.$set() method :

this.$set(this.data,newSectionId, {displayName: 'Custom'})

this issue is solved in Vue 3. and you could just do :

  const newSectionId = Math.floor(Math.random() * 1000); 
      this.data[newSectionId] = {
         displayName: 'Custom'
      }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.