uneeb meer
uneeb meer

Reputation: 973

nested property inside watch event

I know my question maybe a duplicate but i cant find the solultion of my problem anywhere I have an object with some key/values and i want to watch for the changes in all properties,keeping in mind all properties must have separate events here my object

data: () => ({
    filters: {
        All: false,
        AllUSA: false,
        AllSouthAmerica: false,
        AllAsia: false,
        AllEurope: false
    }
}),

watch

 watch: {
    "filters.All": function(val) {
        if (val) {
            this.TrafficSource = Object.assign(...Object.keys(this.TrafficSource).map(k => ({
                [k]: true
            })));
            this.filters = Object.assign(...Object.keys(this.filters).map(k => ({
                [k]: true
            })));
        } else {
            this.TrafficSource = Object.assign(...Object.keys(this.TrafficSource).map(k => ({
                [k]: false
            })));
            this.filters = Object.assign(...Object.keys(this.filters).map(k => ({
                [k]: false
            })));
        }
    },
    "filters.AllUSA": function(val) {
        alert("both event being called")
        this.TrafficSource = Object.assign(...Object.keys(this.TrafficSource).map(k => ({
            [k]: false
        })));
        this.filters = Object.assign(...Object.keys(this.filters).map(k => ({
            [k]: false
        })));

        if (val) {
            this.TrafficSource.Virginia = true;
            this.TrafficSource.California = true;
            this.TrafficSource.Oregon = true;
        } else {
            this.TrafficSource.Virginia = false;
            this.TrafficSource.California = false;
            this.TrafficSource.Oregon = false;
        }

    },
    deep: true
  }

the problem right now is both the watch events are called event though filters.All was invoked, what am i doing wrong?

Upvotes: 2

Views: 220

Answers (1)

hamid niakan
hamid niakan

Reputation: 2851

you can use a watcher with options on filters like this:

watch: {
  filters: {
     immediate: true,
     deep: true,
     handler(newValue, oldValue) {
     // you can write code to tell you which property is changed since you have
       access to the old and new value here
    }
  },
};

this kind of watcher runs immediately when your component loads and then since it has deep: true it will trigger if any property in the object its watching gets changed.

now for the code to track what actually changed you can write something like this:

// all of this code should be done in the watcher's handler
const newVals = Object.values(newValue);
const oldVals = Object.values(oldValue);
const changedVal = [];
newVals.forEach((x, i) => {
  if (x !== oldVals[i]) {
    const result = Object.entries(newValue).filter(y => y[1] === x).flat();
    changedVal.push(result[0]);
  }
});

now you have all the changed keys in the changedVal array in the handler and you can continue with your logic in the handler

Edit: also i don't think changedVal should be an array, you can set it to the changed key and write a switch...case based on that

Upvotes: 1

Related Questions