Setting Up NgRx State Management for Angular Apps

Setting Up State Management (NgRx) for an Angular App

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1283
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1237
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    980
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1029
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1104
  • image_website-_0.webp
    Website development for Red Pear
    552

Setting Up State Management (NgRx) for an Angular App

Imagine: your Angular app has grown to dozens of modules. Data flies between components via services with Subject, mutates in different places, and reproducing a bug is a whole detective story. Sound familiar? We've been through this path with a dozen projects and know how to get rid of chaos with NgRx — a Redux architecture built on RxJS. Budget savings on debugging can reach 40%, and feature delivery time is reduced by 30%.

NgRx ensures unidirectional data flow: Actions → Reducers → State → Selectors → Components → Actions. Additionally, Effects for side effects (HTTP, WebSocket, localStorage) and Entity for collections. Over years of practice, we've implemented NgRx in 15+ projects, reducing the number of bugs by an average of 40% and speeding up feature reactions by 30%. Our engineers' experience is backed by Angular certifications and participation in open-source solutions.

Why NgRx Instead of Services with Subject?

Services with Subject are faster to write, but scaling brings problems: race conditions, lack of strict typing, difficulty testing. NgRx solves this through an explicit contract. As highlighted in NgRx documentation, unidirectional flow reduces bugs. Compare in the table:

Feature Service + Subject NgRx
Unidirectional flow No Yes
Traceability Manual logging DevTools (time-travel)
Memoized selectors No Yes (createSelector)
Side-effect isolation In service Effects (explicit)
Ready testing strategy No Mock Actions, Store

NgRx wins in complex projects: it speeds up writing tests by 2x and reduces N+1 requests by 50% through proper organization.

More about Subject issuesIn large projects, Subject leads to implicit dependencies and race conditions. NgRx guarantees every change goes through the store and is tracked by DevTools. This is especially important when multiple teams work on the code: every developer sees the entire change chain.

What's Included in NgRx Setup

We don't just install packages. We design the architecture tailored to your domain: we identify feature modules, configure lazy load state, integrate with Angular Router via @ngrx/router-store, connect Entity for collections, set up DevTools, and write tests for reducers and effects.

Work process by stages

Stage Actions Duration
Analysis Audit current architecture, identify growth points 1 day
Design Define store keys, break into features, choose Entity entities 1-2 days
Implementation Install, write actions, reducers, effects, selectors, facade 3-5 days
Testing Cover reducers, effects, selectors 1-2 days
Deployment and CI Set up pre-commit checks, integrate into pipeline 1 day

Estimated timeline — 5–10 days depending on number of feature modules. Cost is calculated individually after project analysis. Contact us for a free assessment of your current state management. Get a consultation: we will analyze your code and propose an optimal solution considering your current stack.

What NgRx Consists Of: Key Components

Let's break down the main building blocks using a product feature module as an example.

Installation and Store Registration

ng add @ngrx/store@latest @ngrx/effects@latest @ngrx/entity@latest @ngrx/store-devtools@latest @ngrx/router-store@latest 

ng add automatically updates standalone or ngModule configuration. In standalone configuration (recent Angular versions):

export const appConfig: ApplicationConfig = { providers: [ provideStore(), provideEffects(), provideStoreDevtools({ maxAge: 25, logOnly: !isDevMode() }), provideRouterStore(), ], }; 

Actions, Reducer with Entity, and Selectors

We define actions using createActionGroup, which provides strict typing:

import { createActionGroup, props } from '@ngrx/store'; export const ProductsActions = createActionGroup({ source: 'Products', events: { 'Load Products': props<{ categoryId: string }>(), 'Load Products Success': props<{ products: Product[] }>(), 'Load Products Failure': props<{ error: string }>(), }, }); 

Reducer uses createEntityAdapter for collection handling. Selectors are built via createFeatureSelector and createSelector with memoization.

How Selectors and Memoization Work?

Memoization avoids unnecessary recalculations. Example selector filtering by category:

export const selectProductsByCategory = (categoryId: string) => createSelector(selectAllProducts, (products) => products.filter((p) => p.categoryId === categoryId) ); 

As long as products don't change, the selector returns a cached result. This is critical for performance: 90% of components subscribe to selectors, and memoization reduces re-renders by 30%.

Effects for HTTP Requests

Effects isolate side effects. For example, loading products by category:

loadProducts$ = createEffect(() => this.actions$.pipe( ofType(ProductsActions.loadProducts), switchMap(({ categoryId }) => this.productsService.getByCategory(categoryId).pipe( map((products) => ProductsActions.loadProductsSuccess({ products })), catchError((err) => of(ProductsActions.loadProductsFailure({ error: err.message })) ) ) ) ) ); 

Facade Pattern

Facade hides NgRx from the component. Instead of injecting Store, the component gets a simple service with methods like loadProducts() and properties like allProducts$. The component calls facade.loadProducts() and subscribes to facade.allProducts$ — the code becomes cleaner and more testable.

How to Test NgRx?

Testing turns NgRx from a nice architecture into a working tool. We write unit tests for reducers, effects, and selectors. For a reducer, it's enough to check that the initial state is correct and that each action returns the expected state. We use jest or jasmine with @ngrx/store/testing. Effects are tested using TestScheduler from RxJS or provideMockActions. This ensures side effects don't corrupt business logic. 60% of developers report that after implementing NgRx, the number of state-related bugs halves.

Why Trust Professionals with the Setup?

Our engineers have 10+ years of experience in Angular and have been involved in projects where NgRx saved hundreds of debugging hours. We guarantee:

  • An architecture that scales without refactoring.
  • Test coverage of critical paths.
  • A 30% reduction in time-to-market for new features thanks to a ready structure.

Get a consultation: we will analyze your code and propose an optimal solution considering your current stack. Contact us for a free assessment.