I want to create a ngrx selector
selectResult$
which only emits values once a certain input observable has a certain value.
Lets take this example:
export interface AppState {
data: string[];
settings: string[];
loading: boolean;
}
@Injectable()
export class AppStore extends ComponentStore<AppState> {
selectLoading$ = this.select((state) => state.loading);
selectSettings$ = this.select((state) => state.settings);
selectData$ = this.select((state) => state.data);
selectResult$ = this.select(
this.selectLoading$.pipe(filter((loading) => loading === false)),
this.selectSettings$,
this.selectData$,
(loading, settings, data) => {
console.log('emit new data');
return { loading, data, settings };
}
);
So, I want the selector to only emit values when the selectLoading$
is in state loading = false
.
But I don't get selectResult$
to work properly. The flow is like this:
loading = false
loading = true
selectData$
selectResult$
immediately emits a value. But I would not expect this as there is this filter(loading => loading === false)
operatorThe filter operator (loading === false
) only works for selectloading$
.
The selectSettings$
and selectData$
can still emit, even if loading === true
.
So, you have to filter the combined result.
this.selectResult$ = this.select({
loading: this.selectLoading$,
settings: this.selectSettings$,
data: this.selectData$
}).pipe(
filter( ({loading}) => loading === false ),
map( ({loading, settings, data}) => ({ loading, data, settings }) ),
tap( () => console.log('emit new data') )
);
BTW: use tap for side-effects like logging.