Home > Software engineering >  Vue on changing array object trigger get method to check for changes
Vue on changing array object trigger get method to check for changes

Time:08-09

I have a button component that looks like this

<template>
  <button
    
    :
    @click="onSelection(theValue)"
  >
    {{ theValue.displayText }}
  </button>
</template>

And when it is pressed it sets it isSelected state and emit an event to the parent component

private onSelection() {
    this.theValue.isSelected = !this.theValue.isSelected;
    this.$emit('selected', this.theValue);
}

So far so good the issue is in the parent component. Here I go through all the items that is the array that creates the button components above. The .value property is the unique identifier here so what I do is I look through the array with the item sent from the button component, then when found i use splice to trigger reactivity to replace that array object with the one sent from the button component. When i console.log this it works it shows that isSelected property now is true.

private selectedItem(item: Item) {
  var index = this.itemSelectOptions
    .map((p) => p.value)
    .indexOf(item.value);
  this.itemSelectOptions.splice(index, 1, item);
  console.log(this.itemSelectOptions);
}

But then i have this get method that checks for anyChanges on this array and other things and then render UI based on true/false here. The issue is that when this array get changed the anyChanges method does not react and remains false.

private get anyChanges(): boolean {
  console.log(this.itemSelectOptions);
  return this.itemSelectOptions!.some((p) => p.isSelected);
}

How do i make it so that the anyChanges get method reacts on the changes made to itemSelectOptions which is also an get function

private get itemSelectOptions(): Item[] {
  return this.items
    ? this.items.map((item) => ({
        value: item.id.toString(),
        displayText: item.displayName.toString(),
        isSelected: false,
      }))
    : [];
}

CodePudding user response:

What you want is a watcher on itemSelectOptions

watch: {
    question(newOptions, oldOptions) {
      this.anyChanges(newOptions)
    }
  },

guess it will look smthing like this ^^

https://vuejs.org/guide/essentials/watchers.html#basic-example

CodePudding user response:

The reason this was not working was that since itemSelectOptions where a get function it should/can not be modified. So changing it into a private variable and initializing it solved it like this.

  private itemSelectOptions: Item[] = [];

and then initializing

this.itemSelectOptions = this.items
      ? this.items.map((item) => ({
          value: item.id.toString(),
          displayText: item.displayName.toString(),
          isSelected: false,
        }))
      : [];
  • Related