tezvyn:

NgRx Effects

AI-drafted, machine-checkedSource: ngrx.iointermediate

NgRx Effects handle side effects, like API calls, outside of reducers and components by listening to the stream of dispatched actions and, when a matching action appears, running async work and dispatching a new action with the result.

WHY IT EXISTS NgRx reducers are required to be pure functions: same state and action in, same new state out, with no API calls, no timers, no randomness. Real applications obviously need to call APIs, read local storage, and navigate in response to user actions, none of which is allowed inside a pure reducer. Effects exist to give that necessary impurity a dedicated, testable home, separate from both reducers and components, so the store's update logic stays predictable while side effects still happen somewhere principled.

THE MENTAL MODEL An Effect is a listener standing beside the store, not part of it. It never touches state directly. It watches the stream of every action dispatched across the whole app go by, and when one it cares about appears, it goes off and does something asynchronous, then comes back and dispatches a brand new action describing what happened. It is a translator between something that happened in the world and the resulting action for the store to handle.

HOW IT WORKS An Effect is built with createEffect, wrapping the actions stream, an RxJS Observable of every action dispatched anywhere in the app, piped through ofType with the action it cares about to filter down to just that one. From there, a flattening operator like mergeMap, switchMap, or exhaustMap calls a service method that returns an Observable, typically an HTTP request, then map transforms a successful response into a success action and catchError turns a failure into a failure action. The Effects runtime automatically dispatches whatever action comes out the other end back into the store, so the whole cycle, trigger, side effect, result, stays entirely inside RxJS operators.

WHEN IT MATTERS It matters anywhere state changes need an API call, navigation, or persistence attached to them. The footgun is picking the wrong flattening operator: mergeMap on a search-as-you-type effect fires every keystroke's request in parallel with no cancellation, letting stale responses arrive after fresh ones. switchMap fixes that by cancelling the previous request, but using switchMap on a save action can wrongly cancel an in-progress save if triggered twice, where exhaustMap, which ignores new triggers until the current one finishes, is the correct choice.

ONE CONCRETE EXAMPLE An Effect listens for a loadUsers action, calls the users service with switchMap, and dispatches a loadUsersSuccess action with the response on success or a loadUsersFailure action with the error on failure. The component that needs the list only ever dispatches loadUsers and reads a users selector, never touching the HTTP client itself.

Read the original → ngrx.io

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.