State Management with NgRx
NgRx is a powerful library for managing state in Angular applications. It provides a robust and reactive approach to state management using RxJS. This guide covers setting up and using NgRx for state management in Angular.
Setting Up NgRx
First, install the necessary NgRx packages:
ng add @ngrx/store @ngrx/effects @ngrx/store-devtools @ngrx/entity @ngrx/router-store
Creating State, Actions, and Reducers
Create the state, actions, and reducers for your application:
// actions.ts
import { createAction, props } from '@ngrx/store';
export const loadItems = createAction('[Item] Load Items');
export const loadItemsSuccess = createAction('[Item] Load Items Success', props<{ items: any[] }>());
export const loadItemsFailure = createAction('[Item] Load Items Failure', props<{ error: any }>());
// reducer.ts
import { createReducer, on } from '@ngrx/store';
import * as ItemActions from './actions';
export const initialState = {
items: [],
error: null
};
const _itemReducer = createReducer(
initialState,
on(ItemActions.loadItemsSuccess, (state, { items }) => ({ ...state, items })),
on(ItemActions.loadItemsFailure, (state, { error }) => ({ ...state, error }))
);
export function itemReducer(state, action) {
return _itemReducer(state, action);
}
// state.ts
import { ActionReducerMap } from '@ngrx/store';
import { itemReducer } from './reducer';
export const rootReducer: ActionReducerMap = {
items: itemReducer
};
Configuring the Store
Configure the store in your application's root module:
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { AppComponent } from './app.component';
import { rootReducer } from './state';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
StoreModule.forRoot(rootReducer),
EffectsModule.forRoot([]),
StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: environment.production })
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Creating Effects
Create effects to handle side effects such as API calls:
// effects.ts
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { of } from 'rxjs';
import { catchError, map, mergeMap } from 'rxjs/operators';
import * as ItemActions from './actions';
import { ItemService } from './item.service';
@Injectable()
export class ItemEffects {
loadItems$ = createEffect(() =>
this.actions$.pipe(
ofType(ItemActions.loadItems),
mergeMap(() => this.itemService.getAll()
.pipe(
map(items => ItemActions.loadItemsSuccess({ items })),
catchError(error => of(ItemActions.loadItemsFailure({ error })))
))
)
);
constructor(private actions$: Actions, private itemService: ItemService) {}
}
// app.module.ts (Update)
import { ItemEffects } from './effects';
@NgModule({
...
imports: [
...
EffectsModule.forRoot([ItemEffects]),
],
...
})
export class AppModule { }
Using Store in Components
Use the store in your components to dispatch actions and select state:
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs';
import * as ItemActions from './state/actions';
@Component({
selector: 'app-root',
template: `
Items
- {{ item.name }}
`
})
export class AppComponent implements OnInit {
items$: Observable;
constructor(private store: Store<{ items: any[] }>) {
this.items$ = store.pipe(select('items'));
}
ngOnInit() {
this.loadItems();
}
loadItems() {
this.store.dispatch(ItemActions.loadItems());
}
}
Key Points
- NgRx is a powerful library for managing state in Angular applications using RxJS.
- Install the necessary NgRx packages to get started.
- Create state, actions, and reducers to manage application state.
- Configure the store in your application's root module.
- Create effects to handle side effects such as API calls.
- Use the store in your components to dispatch actions and select state.
Conclusion
NgRx provides a robust and reactive approach to state management in Angular applications. By setting up NgRx, creating state, actions, reducers, and effects, and using the store in your components, you can effectively manage the state of your application. Happy coding!