NgRx
A quick tutorial on working with data in an Angular application

Introduction
Angular is a framework for creating the front-end for web applications. However, it is purely geared toward creating visual components, not for handling domain data. That's where NgRx comes in. It's a library for working with data on the front end in a "Flux" pattern, which is a slight variant of MVC (I like this explanation of it: Flux vs MVC). All modern web frameworks have a typical library like this for handling data. For React, the library is Redux. For Vue, it's Vuex.
Some quick terminology:
- store: a javascript object that holds your data
- state: the store's data at a given point in time
- slice: a property of your store (so just a section of your overall data)
- reducer: a pure function for altering your state
- action: a key and some values used to tell the reducer what slice of state you want to change
- dispatch(): a method used to run actions
- subscribe(): a method used to detect state changes
In a nutshell, using NgRx will look like this:
- import the store at root
- create a reducer for defining and changing state
- import the store and any reducers in your component
- use your reducer by dispatching actions to it
- subscribe to the store to detect when data is changed
What This Tutorial Covers
What This Tutorial Covers
- Installation / Set Up
- Reducers & Actions
- Dispatching Actions
- Subscribing
- Testing
What You Need For This Tutorial
What You Need For This Tutorial
Nothing unless you want to experiment, in which case: a Angular playground with NgRx
NgRx Set Up
You install the library with:
npm i --save @ngrx/store
To enable NgRx, you need to add it to the your app's core module. The value(s) you pass into the forRoot method are the reducers you want to define at the root level, but in this case, we'll just pass in a blank object (reducers are explained later).
Reducers
A reducer is a function that will define and change slices of your entire state.
The reducer receives two parameters, the current state and an action (something you pass in later).
An action has the following structure:
{
type: 'SOME-ACTION',
payload: 'some value'
}
The type property is a string that will match a switch case in the reducer function. The payload property includes some values (like a string or object with multiple values) that you would like to use to change the state.
Create a reducer (it should be in a directory like so: app/state/domain/domain.reducer.ts
):
You can see that the action.type hits a switch statement case, where the state is returned with the mutations you want. You should also know that this is how you initialize state values as well. When the application is first created, all reducers are called, and the default value of state passed to the reducer is used for initialization. Keep in mind though, that this is the default value and not the property. You set the property name in the following step, when you import the reducer and pass it to the store module's forFeature method.
Component Set Up & Dispatching Actions
To use the store in a component, you must add the NgRx module to the component's module along with whatever reducers you want to use:
Now, in your component's code, you can change your state by calling the dispatch method on your store.
Subscribing
Other components can subscribe to changes in your state. Import the module and reducers into the component like the previous step. Then, subscribing is as simple as using the select function to select the property you want to observe and the subscribe method subscribe to changes:
Testing
Testing basically involves importing the the store module using both forRoot & forFeature, and then combining the reducers that are imported. At that point, you can use your store in your unit test. To see a full example, go the following official link:
NgRx Store Testing: Read MeDev Tools
There's a great extension for Chrome where you can see what your state looks like, as well as previous states, in Chrome's developer tools window.
To use it, you first have to add and enable an npm package on your project:
npm i --save @ngrx/store-devtools
To enable the package, add it to your application's root module. The check for environment.production is a flag you can use to omit the tool when building your application for production.
Finally, add the Chrome extension by going to the following link and installing it (although it's called "Redux DevTools", as in the tool used with React, it works with Angular/NgRx as well (as they both use the Flux model):
Redux DevToolsNow, you should see an icon for the Redux DevTools that looks like 3 concentric circles (like a diagram of a solar system or an atom). It should light up when you visit your application. Clicking on it will give you data about the state. You can also click on the "Redux" tab inside of Chrome's developer tools to get more info.
Done!
So that's how you handle state with modern frameworks like Angular.