Konzy262
Konzy262

Reputation: 3087

mobx reaction is failing to trigger when adding to an observable array

I'm attempting to trigger a mobx reaction when an item is added to or removed from an observable array.

Currently it's only triggered when removing an item

type QueryParam = {
    name: string
    value: string
}

export default class SelectStore {
    rootStore: RootStore;
    constructor(rootStore: RootStore) {
        this.rootStore = rootStore;
    }

    @observable testRunFilters: QueryParam[] = [];

    @action updateTestRunFilter = (queryParam: QueryParam) => {
        const existingParam = this.testRunFilters.find(q => q.name === queryParam.name && q.value === queryParam.value);
        if (!existingParam) {
            this.testRunFilters.push(queryParam);
            //console.log('In updateTestRunFilter' + this.testRunFilters);
        }
    }

    @action removeTestRunFilter = (queryParamName: string) => {
        const existingParam = this.testRunFilters.find(q => q.name === queryParamName);
        if (existingParam) {
            this.testRunFilters = this.testRunFilters.filter(q => q.name !== queryParamName);
            //console.log('In removeTestRunFilter' + this.testRunFilters);
        }
    }

    myReaction = reaction(
        () => this.testRunFilters,
        (testRunFilters) => {
            console.log('Hello!' + testRunFilters);
        }
    );
}

The console.log in updateTestRunFilter is being triggered so I'm not sure what is wrong here?

I can't get it to work with a Map either, e.g. @observable testRunFiltersMap = new Map();

Upvotes: 0

Views: 1567

Answers (1)

Ivan V.
Ivan V.

Reputation: 8081

Your reaction is wrong. The way it is now, it will only be triggered when you completely change the array ( new reference ). In order to trigger the reaction, you need to watch for the length property of the array. However, now the parameter that will be passed to the side effect will be just the array length.

   myReaction = reaction(
        () => this.testRunFilters.length,
        (thisIsLengthNow) => {
            console.log('Hello!' + testRunFilters);
        }
    );

But you can always return more stuff from the reaction or just access the array with this.testRunFilters in side effect.

Upvotes: 2

Related Questions