Component Store — Series 2

Preview — 3 of 10 questions

What does it guarantee?

javascript
load$ = createEffect(() => this.actions$.pipe(
  ofType(load),
  switchMap(() => this.api.getAll().pipe(
    tapResponse({
      next: (heroes) => this.store.dispatch(loadSuccess({ heroes })),
      error: (e: HttpErrorResponse) => this.store.dispatch(loadFailure({ error: e.message })),
    }),
  )),
));
AIt retries the request on error
BIt dispatches the actions automatically from their names
CIt converts the observable into a promise
DIt handles both outcomes and stops the error from propagating out of the inner observable — so the outer stream, and the effect, survive a failure

Which runs first?

javascript
save$ = createEffect(() => this.actions$.pipe(
  ofType(saveRequested),
  concatLatestFrom(() => this.store.select(selectDraft)),   // already reflects the reducer
  switchMap(([, draft]) => this.api.save(draft)),
));
AEffects, so state changes can depend on their result
BWhichever was registered first
CReducers — the state is updated for every dispatched action before effects observe it, which is why an effect reading state sees the post-reducer value
DThey run concurrently, with no ordering guarantee

Why concatLatestFrom rather than withLatestFrom?

javascript
concatLatestFrom((action) => this.store.select(selectById(action.id)))
AwithLatestFrom cannot take a selector
BconcatLatestFrom takes a factory, so the selector is only subscribed when an action actually arrives — avoiding work, and avoiding a subscription to state the effect may never need
CwithLatestFrom dispatches its result
DThey are identical; the NgRx version is a re-export

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.