TIL: concatLatestFrom does not wait

The Problem
Today, I learned that concatLatestFrom in NgRx does not wait for an observable to emit a valid value before proceeding. Instead, it simply grabs the latest available value at the time an action is dispatched. If the observable has not emitted yet, your effect might not behave as expected.
Example of Unexpected Behavior
Consider this effect where we try to retrieve a value from the store when actionA is dispatched:
myEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyActions.actionA),
concatLatestFrom(() =>
this.store.select(selectCondition).pipe(
filter(value => value === true) // Only emits when true
)
),
map(([action, condition]) => MyActions.nextAction({ condition }))
)
);
What happens here?
If
actionAis dispatched beforeselectConditionemitstrue, the effect does not wait—it just won’t run or may break.concatLatestFromdoesn’t re-trigger whenselectConditioneventually becomestrue.
The Fix: Use switchMap + combineLatest
If you need to wait until a condition is met, use switchMap and combineLatest instead:
myEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyActions.actionA),
switchMap(() =>
this.store.select(selectCondition).pipe(
filter(value => value === true), // Waits until true
map(value => MyActions.nextAction({ condition: value }))
)
)
)
);
Why This Works:
switchMapstarts a new observable each timeactionAis dispatched.filter(value => value === true)ensures we wait until the condition is met before proceeding.Once
selectConditionemitstrue,nextActionis dispatched.
What If You Need to Wait for Multiple Conditions?
If you need to wait for two conditions to become true, use combineLatest with filter:
myEffect$ = createEffect(() =>
this.actions$.pipe(
ofType(MyActions.actionA),
switchMap(() =>
combineLatest([
this.store.select(selectConditionOne),
this.store.select(selectConditionTwo)
]).pipe(
filter(([cond1, cond2]) => cond1 === true && cond2 === true),
map(([cond1, cond2]) => MyActions.nextAction({ cond1, cond2 }))
)
)
)
);
This ensures that the effect only runs when both conditions are true.
Takeaway
Use concatLatestFrom when you just need the latest value at action dispatch.
❌ Don’t use concatLatestFromif you need to wait for a condition to become true.
✅ Use switchMap + filter (or combineLatest) to wait for conditions.



