Reputation: 3937
I am trying to get 2 selectors with the latest concatLatestFrom that was introduced in NgRx 12, however i cant seem to understand what i am doing wrong and i am unable to achieve this.
I have an effect that looks like this
loadAllCases$ = createEffect(() => this._actions$.pipe(
concatLatestFrom(() => [
this.store.pipe(select(CaseSelectors.getAllCases)),
this.store.pipe(select(CaseSelectors.getCasesLoaded))
]),
navigation(this.caseLandingPage, {
run: (snap, [loaded, cases]) => {
if (loaded) {
return CaseActions.loadAllSuccess();
} else {
return this._caseService.getAll().pipe(
map(cases => CaseActions.loadAllSuccess(cases))
);
}
},
onError: (action, error) => {
return CaseActions.loadAllFailed(error);
}
})
));
However this doesnt seem to work due to type incompatibility
Argument of type 'OperatorFunction<Action, [Action, boolean, Case[]]>' is not assignable to
parameter of type 'OperatorFunction<Action, ActionOrActionWithState<unknown, Action>>'.
Type '[Action, boolean, Case[]]' is not assignable to type 'ActionOrActionWithState<unknown,
Action>'.
Type '[Action, boolean, Case[]]' is not assignable to type '[Action, unknown]'.
Source has 3 element(s) but target allows only 2
However. if i just leave one selector this works fine, is this a case that using concatLatestFrom can only select one selector? Note i have tried chaining them one after the other this produces the same error. Any help or advice appretiated.
This appears to be Nx specific bug, and the navigation pipe it providers, i have oppened a bug related issue with the Nx Repository https://github.com/nrwl/nx/issues/6830
The code in the example works fine if it is piped with any RxJs operation.
Upvotes: 8
Views: 18686
Reputation: 4260
I don't think you need the pipe functions, like this:
concatLatestFrom(() => [
this.store.select(CaseSelectors.getAllCases),
this.store.select(CaseSelectors.getCasesLoaded)
]),
Upvotes: 1
Reputation: 370
There is a type declaration for the concatLatestFrom function and its overloaded version
import { Observable, ObservedValueOf, OperatorFunction } from 'rxjs';
export declare function concatLatestFrom<T extends Observable<unknown>[], V>(observablesFactory: (value: V) => [...T]): OperatorFunction<V, [V, ...{
[i in keyof T]: ObservedValueOf<T[i]>;
}]>;
export declare function concatLatestFrom<T extends Observable<unknown>, V>(observableFactory: (value: V) => T): OperatorFunction<V, [V, ObservedValueOf<T>]>;
https://github.com/ngrx/platform/blob/12.4.0/modules/effects/src/concat_latest_from.ts
So you're right this function accepts either a single observable or an array of observables.
But it seems you're using order of operators in a wrong way
I'm not sure what does navigation and caseLandingPage mean, but this example might give you an idea of how to fix/improve your effect handler
public readonly something$ = createEffect(
() =>
this.actions$.pipe(
ofType(someAction),
concatLatestFrom(() => [
this.store.select(selectFoo),
this.store.select(selectBar),
]),
switchMap(([action, foo, bar]) => {
// Do what you need
}),
),
);
Upvotes: 14
Reputation: 15505
Hmmmm, the types accept an array of selectors and there's also a test to verify that it works.
Do you have a runnable reproduction? The problem will probably be something else.
The error itself mentions the correct types returned by concatLatestFrom
, so my guess would be that the navigate
operator needs to be tweaked.
Type '[Action, boolean, Case[]]' is not assignable ...
Upvotes: 1