Angular and NgRx
  • Introduction
  • Setup
  • 1. Create an application
  • 2. Create a home component
  • 3. Test HomeComponent
  • 4. Create event feature module
  • 5.Create AddAttendeeComponent
  • 6. Test AddAttendeeComponent
  • 7. Listen to child component events
  • 8. Add test for the event emitter
  • 9. Create EventListComponent
  • 10. Test EventListComponent
  • 11. Create EventService
  • 12. Test EventService
  • 13. Add simple NgRx spinner
  • 14. Test reducer
  • 15. Strongly type our store
  • 16. Update reducer tests
  • 17. Store dev tools
  • 18. Create selectors
  • 19. Create feature state
  • 20. Create effect
  • 21. Test an effect
  • 22. Use Entity Adapter
  • 23. Add attendee logic
  • 24. Router store
  • 25. Fix EventComponent tests
Powered by GitBook
On this page
  • 1. npm install @ngrx/entity
  • 2. Make an entity adapter
  • 3. Update reducer to use entity adapter collection methods
  • 3. Update selectors
  • StackBlitz Link

22. Use Entity Adapter

In this section, we will normalise our state into dictionaries to make it easier to manage, query and project our state. This is one of the most important steps to make better redux.

1. npm install @ngrx/entity

Entity State adapter for managing record collections. @ngrx/entity provides an API to manipulate and query entity collections.

  1. Reduces boilerplate for creating reducers that manage a collection of models.

  2. Provides performant CRUD operations for managing entity collections.

  3. Extensible type-safe adapters for selecting entity information.

  • npm install the library

npm i @ngrx/entity

2. Make an entity adapter

  • make an adapter and use it to make the initial state and manage collections.

src/app/event/state/attendees/attendees.reducer.ts
<---------- ABBREVIATED CODE SNIPPET ---------->

import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';

import { AttendeesActions, AttendeesActionTypes } from './attendees.actions';
import { Attendee } from '../../../models';

export interface State extends EntityState<Attendee> {
  loading: boolean;
  error: any;
}

const adapter: EntityAdapter<Attendee> = createEntityAdapter<Attendee>();

export const intitalState: State = adapter.getInitialState({
  loading: false,
  error: null
});

export function reducer(state = intitalState, action: AttendeesActions): State {

<---------- ABBREVIATED CODE SNIPPET ---------->

3. Update reducer to use entity adapter collection methods

Method

Action

addOne

Add one entity to the collection

addMany

Add multiple entities to the collection

addAll

Replace current collection with provided collection

removeOne

Remove one entity from the collection

removeAll

Clear entity collection

updateOne

Update one entity in the collectionaddOne

updateMany

Update multiple entities in the collection

upsertOne

Add or Update one entity in the collection

upsertMany

Add or Update multiple entities in the collection

  • Change out manual collection management for adapter collection methods.

  • Make selectors from the adapter with adapter.getSelectors method.

src/app/event/state/attendees/attendees.reducer.ts
import { EntityState, EntityAdapter, createEntityAdapter } from '@ngrx/entity';

import { AttendeesActions, AttendeesActionTypes } from './attendees.actions';
import { Attendee } from '../../../models';

export interface State extends EntityState<Attendee> {
  loading: boolean;
  error: any;
}

const adapter: EntityAdapter<Attendee> = createEntityAdapter<Attendee>();

export const intitalState: State = adapter.getInitialState({
  loading: false,
  error: null
});

export function reducer(state = intitalState, action: AttendeesActions): State {
  switch (action.type) {
    case AttendeesActionTypes.LoadAttendees: {
      return adapter.removeAll({
        ...state,
        loading: false,
        error: null
      });
    }

    case AttendeesActionTypes.LoadAttendeesSuccess: {
      return adapter.addAll(action.payload, {
        ...state,
        loading: false,
        error: null
      });
    }

    case AttendeesActionTypes.LoadAttendeesFail: {
      return adapter.removeAll({
        ...state,
        loading: false,
        error: action.payload
      });
    }

    default: {
      return state;
    }
  }
}

export const {
  selectIds,
  selectEntities,
  selectAll,
  selectTotal
} = adapter.getSelectors();

3. Update selectors

  • Update attendee selectors to use the new adapter getSelector methods.

src/app/event/state/attendees/attendees.selectors.ts
import { createFeatureSelector, createSelector } from '@ngrx/store';
import * as fromAttendee from './../attendees/attendees.reducer';
import { EventState } from '..';

export const getEventState = createFeatureSelector<EventState>('event');
export const getAttendeeState = createSelector(
  getEventState,
  state => state.attendees
);

export const getAttendees = createSelector(
  getAttendeeState,
  fromAttendee.selectAll
);

StackBlitz Link

Previous21. Test an effectNext23. Add attendee logic

Last updated 6 years ago

The entity adapter will allow us to take a collection and manage it with a set of Adapter Collection Methods. The entity adapter also provides methods for operations against an entity. These methods can change one to many records at a time. Each method returns the newly modified state if changes were made and the same state if no changes were made. You can read more here .

https://github.com/ngrx/platform/blob/master/docs/entity/adapter.md
Duncanhunter - Angular And Ngrx Demo App - StackBlitzStackBlitz
Web Link: Link to the demo app running in StackBlitz
Entity adapter making new ids and entities dictionaries.
Logo