Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

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!