Using NGRX in Angular 7 Applications
from a react developer’s point of view
Thinking in Redux:
If you have ever used Redux in a React application much of this will feel right at home. I know a lot of people that don’t like Redux but I am not one of those people. Having a central location to store and access application state makes everything feel so much cleaner.
Angular in particular feels like a mess to me. Input’s and Ouput’s every where to communicate between child and parent components makes following the flow of the application daunting. Imagine instead, having everything in one spot for you to easily grab with a simple method call. That’s what I will be showing you today. First let me give you a description of the main components of Angular’s version of Redux, NGRX, and how they all work together.

Above is the flow of a typical ngrx application. I know it seems complicated but I promise it will become second nature in no time.
The Store:
The store is where all application state will be stored. There can only be one store (army), however, you can have multiple sub-stores(battalions) that you can combine into one root store. I’ll show you that later.
Actions:
Think of actions as a messenger. The messenger can send orders from the component to the reducer, that message can simply contain instructions or it can contain instructions along with a payload. Anytime you want to communicate a change to the store you send an Action (with or without a payload) to the Reducer.
Reducers:
The Reducer is the real action man. It will take the message from the action and any payloads it may or may not have and it will enact those instructions and perform any necessary changes to the store.
Selectors:
Selectors are our way of getting data back from the store and using it throughout the application. If the piece of state your grabbing is expected to change throughout the flow of the application you may want to subscribe to this change.
Effects:
Effects are a little more complicated. Effects will basically listen for a specific action, when it hears that action being dispatched it will intercept it, perform a little magic of it’s own (aka make an http request and return the data), then return the data back into the typical application flow.
Key Recommendation:
The best thing you can do is set up models for, at a minimum, your responses. For instance, the project I was given at work was pretty simple, I knew that I was going to call a back-end service and get the same data every time. With that in mind I created an interface that laid out exactly what my data was going to look like so I could easily map the response from the http service, to the Response Model interface I created.
Walking through a real-life application
This won’t be a tutorial you can follow along with, you won’t have access to the back-end service needed to follow this, but it should give you a good idea of how to think about the flow of your application with a Redux mindset and the general syntax you will need.
The General Flow:
When I am adding new components to an app I typically follow this general flow:
- Define a model, or add to a model
- Add to inital state if necessary
- Create the action
- Create the reducer or effect (if calling an outside service)
- Create the selector
- Use the action or selector in the component
In a Fresh application:
First step is to install ngrx:
npm install @ngrx/core @ngrx/effects @ngrx/storeSecond step:
Start thinking about models and how you will shape your data and application state. For my application I separated my Event state and my Data state into two separate models. I also have an error model, request model, response model and an app-state model, which will combine the data I need into one central model to reference in my main Application state.
AppState should always contain an instance of EventState and ResponseModel (which will outline the data we should get from the http service):

Event state will handle all of the event state, basically anything we would typically have to send through input/outputs, the change of a radio button selection or tab, if there is an error or if a form was submitted.

The Response model will contain the model for the data we receive from our http call. It will also hold any error messages, the loading status and the currently selected client and policy.

That should be enough for you to get a general idea of the data we will be handling.
Third:
Define your initial state and add a method to retrieve the state. If you created an application state model you should set the initial app state to that type to incorporate consistency. As you can see below my initial state is of type AppState and the getter will return a type of AppState. Consistent ;)

I did the same for event and data state as well (you only need the getter method for your MAIN application state, remember you can only have ONE STORE, but you can have multiple sub-stores data and event state will be sub-stores):

Fourth, Actions:
Like I said before I decided to separate my applications events and it’s data into two separate sub-stores, In order to keep everything clean I also broke up the actions, selectors, reducers and effects accordingly. So I needed a new action file for each sub-store.
For actions you basically need a new class for each Action, each of these classes will implement Action from the @ngrx/store library. It requires at minimum one attribute to be implemented. It MUST have a type.
The best way to set the actions up is to start with an enum. In the enum you will define the class names you intend to use (make them meaningfull) and assign those to a string value, for example:

Now you can go down the line and create the classes you need. Try to determine if the action will be sending a payload (parameters) to the reducer. If so you will need to add a constructor and inject that payload into the class. For example:

Fifth, Reducers:
Now you can move on to the reducers. Remember reducers are where all the changes and state manipulations will occur. Just like in React, the reducer will be a switch statement. It will need access to the inital state of the sub-store it is accessing. For Example:

Sixth, Effects:
Like I said earlier, Effects get a little more complicated. They wait for a specific Action to be called, and intercept it before it reaches the reducer. Then it will call your http service and return the data back into the application flow (sending it to the reducer).
In my application the Action the Effect is waiting to hear is EDataActions.NewDataByClient OR EDataActions.NewDataByPolicy, once it hears that one of them is called it will intercept it, call the http service and take the data it received and send it out by dispatching another Action (DataReceived). The payload will be the response from our http call.

- As you can see each Effect needs to be decorated with a new @Effect() decorator.
- It will also return an Observable<Action>
- You will tell it what Action to listen to by using ofType
- You will grab the payload (if there is one) and pass it to a switchMap
- The switchMap will handle the call and pipe the data then map it into the payload of our new Action dispatch.
At this point, the new DataReceived action gets sent to the Reducer, carrying our http response data. Once there it will set the state to our action.payload:

If you didn’t separate your store’s you may want to use this return statement instead, to avoid overriding any other state you may have in the initalState:
return {
...state,
someVarNameHere: action.payload
}Seventh, Selectors:
Selectors are the easy part. Like I said before we use these to pick out parts of the state we need for certain components.
The only thing Selectors need is an import from the ngrx/store library, “createSelector”. After that is imported you need at minimum two methods.
The first will grab the full application state and select the sub-store we need. (Remember we added that getter in the AppState). Example:

The next method we will need is the one to create the actual selector and return the exact data we need! The createSelector method requires two parameters, the state that you are accessing, and a callback.

I gave you a few examples here, but let’s go over what is happening.
- We import createSelector from @ngrx/store.
- We get the sub-store we need from our AppState
- Then we create and export selectors by calling createSelector and passing it our getDataState method and passing it a call back that will return the slice of the store we want.
Tenth, combining Reducers and stores:
So if you have kind of followed my methods of seperating everything and making a model to combine all of your models and states into one AppState/AppStateModel then your state (or store) should already be combined, all we have to do is combine the reducers.
To do this, you will need an index.ts file in your store folder. You’ll need to import the following, along with any reducers and your AppState model:
import { ActionReducerMap } from '@ngrx/store';Now that you have that imported you need to create and export a object with a type of ActionReducerMap<AppState>. This will essentially look at your AppState model and any reducers you add and put everything where it belongs.
For example, the AppState model declares that it must have two values, eventState of type EventState (model) and response of type ResponseModel (model).
If you go back to your Reducers, you will see that the reducer returns a type, for me eventReducer returns a type of EventState and dataReducer returns a type of ResponseModel.

So with that in mind, when we combine our reducers by doing the following, it will be valid thanks to our models!:

Ninth, adding NGRX effects and Store in AppModule:
Now you have all the little pieces together, it’s time to let your application know what’s going on.
Go into your app.module and import the following, along with your combined reducers and any Effects you declared:
import { StoreModule } from '@ngrx/store';import { EffectsModule } from '@ngrx/effects';
Now in your imports section of the ngModule you need to add the following:
StoreModule.forRoot(appReducers), // replace appReducers with the name of your reducerEffectsModule.forRoot([DataEffects]), // replace DataEffects with the names of your Effect, luckily you do not have to combine these you can just pass in an array of Effects
That is it for the boiler plate!
Using State in the Application
You’ve done all of the hard work, you’ve set up all of your boiler plate code and finally you can start using your store. In order to bring these values into the UI though we have to revisit our selectors.
Injecting the store into the component:
First thing’s first, you need to let the component know where it’s gunna be getting all of this glorious data. So we have to inject the Store as we would an Injectable service. Let’s walk through it:
- Import the following:
import { Store, select } from '@ngrx/store';2. Import your AppState model as well
3. Create a variable in the constructor and set the type to Store<yourappstatemodelhere>. Example:

Now the store is available to the component! So now, how do we select our data? Remember how I told you Selectors were how we retrieve store data for the components? We will need to import the selectors we need and use a method provided by ngrx called select. Select takes one parameter, the selector we created. I’ll show you an example of how I applied this, then we will walk through it.

So let’s walk through this.
- At the top of our class we define the variables and types we will need, including the ones we will get from the selectors.
- Then, because I needed the variables when the component initialized, I call this.store.select(selectorNameHere) and subscribe to the result. This allows me to get instant updates in the UI if that data changes in the store.
- Now you can use your variables however you normally would.
Dispatching Actions in Components:
So now I can get store state and view it in the UI, but I need to be able to change it when x happens. No problem.
Earlier we set up Actions. Anytime you want to modify state in the store you need to dispatch an action. Actions tell the reducer exactly what you want to do and provide the data it needs to do so, in the form of payloads.
From here I will assume you are in the same component where we injected the Store earlier. So, say I clicked some thing and now it needs to toggle the loading state, the reducer needs to know that that happened so it can change the application state and trigger our loading logic.
To do this all we have to do is call this.store.dispatch() and pass it a new instance of the Action class we want to invoke. Example:

Here we call the dispatch method and create a new instance of the ToggleLoading class, we pass it a boolean, this boolean will be sent to the action class and assigned as it’s “payload” which will then get sent to our reducer…


That’s it!
Wrapping up:
I know this was a lot and it may seem overwhelming but I promise very quickly, your mind will automatically recognize the pattern and learn how to ask yourself helpful questions. “Ok, I need a new component..”:
- “What data does it need?”
- “Do I have a model defined for that data or do I need to create a new model for it?”
- “Will I need to dispatch any actions”
- “Will I need to make any http calls”
- “Will I need to get this data in realtime from the store?”
- “Alright, I’ve set up the model and state, now does this component need access to any data from the store? Yes.. ok I need to make a selector”
… and so on. Once you start thinking in this cause and effect type logic Redux (NGRX) will seem a lot more natural.
Thanks for reading and let me know if I jacked anything up :)
