Building a CRUD application with Angular using Ngrx – part 1

In this guide, we just focus on how to build a CRUD application with Angular (version 8) that has already installed the Ngrx, not on setting up an Angular application or installing the Ngrx library. You can follow the following guides to do those task:

If you have no idea what is Ngrx, I recommend you to read this to explore more about it. And if you have a basic knowledge of Redux, I think you will be easy to approach this library.

In this part, we will learn how to define actions, reducer, selectors and build a page to display all items that are selected from the store using the Ngrx.

In almost any application that we work with, we all encounter operations such as retrieving data, rendering it as a table view, create/update or delete a row on that view. And this data which is stored on the server is dealt with by the usage of HTTP requests (GET, POST, etc).

The first thing we need to do in here is where the data is stored that we will get through an HTTP API request. Because this article does not focus on this, I will use a fake backend server for mock. There are different ways to use a fake back-end server are:

  • Use Angular In-Memory-Web-API
  • Create a local JSON file and use it
  • Or hard-code the data, and return this data.

But I have another easy way, say big thanks to Just provide some rows of code, we already have a RESTful API for mock or testing. I have created a mock RESTful API on for CRUD on the Entity object as below:

Fake RESTful APIs: (CRUD)
GET: (Get all)
GET:{id} (Get one)
POST: (Create)
PUT:{id} (Update)
DELETE:{id} (Delete)

Ok, we have done on prerequisite items. Next, we’ll go together to define actions, reducer, and selectors to fetch Entity objects from the fake server I have created before and store it into the Ngrx store. If you have developed with a React Redux application before, all fundamental principles about Redux (action, reducer, selector, etc) will be similar to the Ngrx.

First, we will define a class that describes all properties of the Entity object we will deal with:

 * Define class that describes all properties of Entity object 
export class Entity {
  id: number;
  name: string;
  code: string;

Let’s define some actions for loading entities as:

import { createAction, props } from "@ngrx/store";

import { Entity } from "../entity";

export enum EntityActionTypes {
  LoadEntities = "[Entity] Load Entities",
  LoadEntitiesSuccess = "[Entity] Load Entities Success",
  LoadEntitiesFail = "[Entity] Load Entities Fail"

export const loadEntities = createAction(EntityActionTypes.LoadEntities);

export const loadEntitiesSuccess = createAction(
  props<{ data: Entity[] }>()

export const loadEntitiesFail = createAction(
  props<{ error: Error | any }>()

export const fromEntityActions = {

Next, we’ll define the Entity’s reducer. Here, we have to define an initial state and specify how the state is changed for each action is sent to the store.

import { createReducer, on, Action } from "@ngrx/store";
import { EntityState, EntityAdapter, createEntityAdapter } from "@ngrx/entity";

import { fromEntityActions } from "./actions";
import { Entity } from "../entity";

export const ENTITY_FEATURE_KEY = "entity";

export interface State extends EntityState<Entity> {
  loaded: boolean;
  error?: Error | any;

export const adapter: EntityAdapter<Entity> = createEntityAdapter<Entity>({
  // In this case this would be optional since primary key is id
  selectId: item =>

export interface EntityPartialState {
  readonly [ENTITY_FEATURE_KEY]: State;

export const initialState: State = adapter.getInitialState({
  // Additional entity state properties
  loaded: false,
  error: null

const _reducer = createReducer(
  on(fromEntityActions.loadEntitiesSuccess, (state, { data }) => {
    return adapter.addAll(data, {
      loaded: true
  on(fromEntityActions.loadEntitiesFail, (state, { error }) => {
    return {
  on(fromEntityActions.loadEntitySuccess, (state, { id, item }) => {
    return adapter.addOne(item, state);
  on(fromEntityActions.loadEntityFail, (state, { error }) => {
    return {

export function reducer(state: State | undefined, action: Action) {
  return _reducer(state, action);

Continue define selectors:

import { createFeatureSelector, createSelector } from "@ngrx/store";

import { State, adapter, ENTITY_FEATURE_KEY } from "./reducer";

// Lookup the 'Entity' feature state managed by NgRx
const getEntityState = createFeatureSelector<State>(ENTITY_FEATURE_KEY);

// get the selectors
const { selectIds, selectAll, selectTotal } = adapter.getSelectors();

// select the array of Entity ids
export const selectEntityIds = createSelector(

// select the array of Entitys
export const selectAllEntities = createSelector(

// select the total Entity count
export const selectEntityCount = createSelector(

// select entity loaded flag
export const selectEntityLoaded = createSelector(
  state => state.loaded

// select entity error
export const selectError = createSelector(
  state => state.error

Create a service file to fetch data from the server:

import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";

  providedIn: "root"
export class EntityService {
  constructor(public http: HttpClient) {}

  getEntities() {
    return this.http.get(``);

To read data from the server, we need to create a side effect to make an HTTP request to the server and store data into the store through Ngrx actions. With React, Saga can handle side effects for us. And the Ngrx also has provided the Effect concept that is the same as the Saga. As the Ngrx documentation: “Effects are an RxJS powered side effect model for Store. Effects use streams to provide new sources of actions to reduce state based on external interactions such as network requests, web socket messages and time-based events.” So that we will use it for reading Entity data from the server.

import { Injectable } from "@angular/core";
import { Actions, createEffect, ofType } from "@ngrx/effects";
import { of } from "rxjs";
import { map, switchMap, catchError } from "rxjs/operators";

import { fromEntityActions } from "./actions";
import { EntityService } from "../entity/sevices/entity.service";

export class EntityEffects {
  loadEntities$ = createEffect(() =>
      switchMap(() =>
          map((res: any) =>
          catchError(error =>

    private actions$: Actions,
    private entityService: EntityService
  ) {}

Finally, creating an Angular page (with route is “/entities”) to display a list of the entity that are fetched from the server. For easy to navigate to entities page, we create a link for quick navigation in app.component.html:

<a [routerLink]="['entities']">Go to Entities</a>

In, the store will dispatch loadEntities action and the effect will be triggered to fetch data from server and store data into the store. Since the data is loaded to the store, we only get data from the store and display it.

import { Component, OnInit } from "@angular/core";
import { Store, select } from "@ngrx/store";

import { selectAllEntities } from "../../../store/selectors";
import { fromEntityActions } from "../../../store/actions";

  selector: "entities-page",
  templateUrl: "./"
export class EntitiesPage implements OnInit {
  title = "Entities Page";

  entities$ =;

  constructor(private store: Store<any>) {}

  ngOnInit(): void {;

The entity template HTML file:


<div *ngFor="let entity of (entities$ | async)">
    Entity Id: {{}} | Name: {{}} | Code: {{entity.code}}

Note: Ensure that you have already imported CommonModule to use the async pipe.

Gives the result as:

The operation for reading Entity data from the server has completed. But you will see the entities page display empty page before render list of Entity objects. This is the cause of waiting from the server for reading data and it should be better for the user’s experience if a spinner display instead of. That is a good suggestion since I know Angular Resolve. Resolve will wait for the data to be resolved before the page is finally navigated.

So I will define the resolver for entities page as below:

import { Injectable } from "@angular/core";
import { Resolve } from "@angular/router";
import { Store, select } from "@ngrx/store";
import { Observable } from "rxjs";
import { filter, take } from "rxjs/operators";

import { fromEntityActions } from "../../store/actions";
import { EntityPartialState } from "../../store/reducer";
import { selectEntityLoaded } from "../../store/selectors";

export class EntitiesResolver implements Resolve<boolean> {
  constructor(private store: Store<EntityPartialState>) {}

  resolve(): Observable<boolean> {
    const loaded$ =;

    return loaded$.pipe(
      filter(loaded => {
        if (loaded === false) {

        return loaded;

As above code, the entities page only is activated if the loaded flag is true. Also, I have added a filter operator to dispatch loadEntities action if the loaded flag is false. So the application only makes an HTTP request only the loaded flag is false, this reduces significantly backend traffic during the application navigation.

Update the to comment or remove the following code:


Continue to add the resolve to the route configuration:

export const entityRoutes: Routes = [
    path: "",
    component: EntitiesPage,
    resolve: {
      entities: EntitiesResolve

Enjoy the result:

CRUD Angular NGRX (Part 1) – CodeSandboxCodeSandbox is an online editor tailored for web


Coming to the end of this guide, let us have a quick recap of what we did.

  • Use to quick create a fake server for mocking and testing.
  • Use createActioncreateReducer, and createFeatureSelector for creating actions, reducer, selectors.
  • Use Ngrx Effect for handle side effects to make an HTTP call for retrieving data from the server.
  • Use Angular Resolver to ensure that data has already loaded before the page is navigated.

I hope this tutorial will be helpful to you 😀

About Author:

Leave a Comment

Your email address will not be published. Required fields are marked *