What is @ngrx/effects?
@ngrx/effects is a library for managing side effects in Angular applications using the Redux pattern. It allows you to isolate side effects from your components and services, making your code more predictable and easier to test.
What are @ngrx/effects's main functionalities?
Handling Side Effects
This code demonstrates how to handle side effects using @ngrx/effects. The `loadItems$` effect listens for the `loadItems` action, calls a service to fetch data, and then dispatches either a success or failure action based on the result.
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { MyService } from './my-service';
import * as MyActions from './my-actions';
@Injectable()
export class MyEffects {
loadItems$ = createEffect(() => this.actions$.pipe(
ofType(MyActions.loadItems),
mergeMap(() => this.myService.getAll().pipe(
map(items => MyActions.loadItemsSuccess({ items })),
catchError(() => of(MyActions.loadItemsFailure()))
))
));
constructor(
private actions$: Actions,
private myService: MyService
) {}
}
Combining Multiple Effects
This code demonstrates how to combine multiple effects in a single class. The `loadItems$` effect handles loading items, while the `updateItem$` effect handles updating an item. Both effects listen for their respective actions and call the appropriate service methods.
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { MyService } from './my-service';
import * as MyActions from './my-actions';
@Injectable()
export class MyEffects {
loadItems$ = createEffect(() => this.actions$.pipe(
ofType(MyActions.loadItems),
mergeMap(() => this.myService.getAll().pipe(
map(items => MyActions.loadItemsSuccess({ items })),
catchError(() => of(MyActions.loadItemsFailure()))
))
));
updateItem$ = createEffect(() => this.actions$.pipe(
ofType(MyActions.updateItem),
mergeMap(action => this.myService.update(action.item).pipe(
map(() => MyActions.updateItemSuccess({ item: action.item })),
catchError(() => of(MyActions.updateItemFailure()))
))
));
constructor(
private actions$: Actions,
private myService: MyService
) {}
}
Error Handling
This code demonstrates how to handle errors in effects. The `loadItems$` effect catches any errors that occur during the service call and dispatches a `loadItemsFailure` action with the error information.
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import { MyService } from './my-service';
import * as MyActions from './my-actions';
@Injectable()
export class MyEffects {
loadItems$ = createEffect(() => this.actions$.pipe(
ofType(MyActions.loadItems),
mergeMap(() => this.myService.getAll().pipe(
map(items => MyActions.loadItemsSuccess({ items })),
catchError(error => of(MyActions.loadItemsFailure({ error })))
))
));
constructor(
private actions$: Actions,
private myService: MyService
) {}
}
Other packages similar to @ngrx/effects
redux-saga
redux-saga is a library that aims to make side effects (e.g., asynchronous actions like data fetching) easier and more manageable in Redux applications. It uses generator functions to handle side effects, which can make the code more readable and easier to test compared to @ngrx/effects.
redux-thunk
redux-thunk is a middleware that allows you to write action creators that return a function instead of an action. This function can then perform asynchronous dispatches. While simpler than @ngrx/effects, it can become harder to manage as the complexity of side effects grows.
mobx
MobX is a state management library that makes it simple to connect the reactive data of your application with the UI. Unlike @ngrx/effects, MobX uses observables to manage state and side effects, which can be more intuitive for some developers.
12.0.0-beta.0 (2021-04-27)
Bug Fixes
- component: include files in ng-add schematics (ad13c9c)
- component-store: include files in ng-add schematics (bfef622)
- data: include files in ng-add schematics (526edd9)
- effects: ng-add schematics will generate effects files properly (4389307)
- entity: include files in ng-add schematics (4d9f647)
- router-store: include files in ng-add schematics (eb71d5c)
- store: ng-add schematics will generate router files if minimal set to false (74a2671)
- store-devtools: include files in ng-add schematics (ac706de)
build
- update to Angular libraries to version 12 RC.0 (#3000) (4fb030e)
- update to Nx version 12.0.x and TypeScript 4.1.x (#2999) (cb258cb)
Features
BREAKING CHANGES
- Minimum versions of Angular and TypeScript have been updated
BEFORE:
Minimum of Angular version 11.x
Minimum of TypeScript 4.1.x
AFTER:
Minimum of Angular version 12.x
Minimum of TypeScript 4.2.x
- The minimum TypeScript version has been updated to 4.1.x
BEFORE:
The minimum TypeScript version is 4.0.x
AFTER:
The minimum TypeScript version is 4.1.x
<a name="11.1.1"></a>