# 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:

```plaintext
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 `actionA` is dispatched **before** `selectCondition` emits `true`, the effect does **not** wait—it just won’t run or may break.
    
* `concatLatestFrom` doesn’t re-trigger when `selectCondition` eventually becomes `true`.
    

## The Fix: Use `switchMap` + `combineLatest`

If you need to wait until a condition is met, use `switchMap` and `combineLatest` instead:

```plaintext
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:

* `switchMap` starts a new observable each time `actionA` is dispatched.
    
* `filter(value => value === true)` ensures we **wait** until the condition is met before proceeding.
    
* Once `selectCondition` emits `true`, `nextAction` is 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`:

```plaintext
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** `concatLatestFrom`**if you need to wait for a condition to become** `true`**.**  
✅ **Use** `switchMap` **+** `filter` **(or** `combineLatest`**) to wait for conditions.**
