vue.jsvuejs3vue-componentstore

Watcher does not detect changes occured to an array of objects


I am using vue3 with options api as shown in the section titled code. I set an object to a store. storeTest.vue shows how the Store is implemented, and in watch it shows how I listen to changes that occurred in the store.

At run time, despite there being values assigned to either of geojson and order, the watch statement does not report any changes occurring. I expect that the values assigned to geojson and order are to be printed in the console, but nothing gets displayed.

Why that is happening and how to solve it?

code:

StoreTest.setters.set({
    geojson: this.#featureRecentlyRequestedProcessing.value.get(DigitizePolygonConstants.CONST_DIGITIZED_FEATURE_PROPERTY_GEOJSON.description),
    order: this.#featureRecentlyRequestedProcessing.value.get(DigitizePolygonConstants.CONST_DIGITIZED_FEATURE_PROPERTY_GEOM_ORDER.description),
});

storeTest.vue:

<script>
import { reactive } from 'vue';

export default {
  }

export const StoreTest = ({
  state: reactive({
    array: [],
  }),
  getters: {
    get() {
      return StoreTest.state.array;
    },
  },
  setters: {
    set(obj) {
        StoreTest.state.array.push(obj);
    },
  },
  actions: {
    initialize() {
        StoreTest.state.array = [];
    },
  }
});
</script>

watch:

created() {
    console.log(verboseTag, 'created()');

    this.$watch(this.refStoreTest.getters.get, (newVal, oldVal) => {
        msg = JSON.stringify({msg: verboseTag + '@watch refStoreTest.getters.get()', newVal: newVal, oldVal: oldVal});
        console.log(msg);
        newVal = newVal.sort((a,b) => a.order-b.order);
        this.refStroeRecentlyHoveredGeometriesProps.setters.set(newVal); 
    });
}

Solution

  • As @EstusFlask and the documentation point out, the $watch config needs to be the third argument:

    In your case:

    this.$watch(
      // first arg
      this.refStoreTest.getters.get,
      // second arg
      (newVal, oldVal) => {
        const sorted = [...newVal].sort((a, b) => a.order - b.order)
        console.log(
          JSON.stringify(
            {
              msg: verboseTag + '@watch xcx refStoreTest.getters.get()',
              newVal,
              oldVal,
              sorted
            },
            null,
            2
          )
        )
        this.refStroeRecentlyHoveredGeometriesProps.setters.set(sorted)
      },
      // third arg
      { deep: true }
    )
    

    Side notes: