'ngrx selector return same values multiple times

I have a

export const selectIDs = creteSelector(
    selectorFeature,
    (feature: Feature) => {
        return feature?.metadata?.ids || []
    }
}

in the component I have

this.store.select(selectIDs).subscribe((ids) => dosomething(ids))

When the system is up feature is undefined so [] is passed into the callback. Then feature then changes to a normal value but .metadata not available so select returns [] which is same as last result so the dosomething() call back is not supposed to be called. But it actually get called again in my code with []

My question is if both time selector returns a [], shouldn't the calllback (those calls in subscribe)be called once?

Or generally I mean if I do this:

this.store.select(featueSelector).subscribe((feature) => console.log(feature)

suppose global state changes 10 times, but feature stays same so featureSelector returns same feature, will the console.log() be called 10 times? I imagine the console.log() will only be called when what feature selectore returns is different from last time?

Thanks

=================== updated ============= it turns out this.store.select() returns a observable, so when the obserable calls the next(), console.log() will be called.

Ngrx selector memorize means it directly returns same value if input is same.



Solution 1:[1]

The selector is fired again, and a new array instance is returned. Because [] === [] is falsy, the new instance is passed to the subscribe method.

As a workaround, you can:

  • filter our empty array: this.store.select().pipe(filter(arr => arr.length > 0 )).subscribe())
  • use the distinct operator: this.store.select().pipe(distinct(insertCheckHere)).subscribe())
  • I think you can also create a variable const empty = [] and return empty in the selector instead of []

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 timdeschryver