Play by Play: Angular and NgRx Overview

Welcome to this overview of the Pluralsight course Play by Play: Angular and NgRx by Duncan Hunter and Lars Klint.

Pluralsight now have a few different courses on NgRx, including the Getting Started course which I have already written about, and also features Duncan Hunter.

This course is a better option for you if you want to get a good overview of this technology, and maybe decide whether it is for you, in under 2 hours.

This course was recorded in late 2017. NgRx is a fast moving technology so some aspects are a little different now, however the fundamentals are pretty much the same in 2020.

The first 10 minutes introduce the ngrx library and the Redux pattern that it is based on.

Duncan then explains the components: The store, the reducer, and the Effects library. At this stage, we are seeing slides to explain the concepts rather than code.

In the “Installing and ngrx and Creating the structure” module, we dive into the coding.

We have a simple app that displays a list of companies with Name, Email, Phone number. Each company has an edit and a delete button associated with it. At the point, there is no NgRx used in this app.

We install the ngrx store with:

npm install @ngrx/store

If we also want the effects library we do

npm install @ngrx/effects

And the dev tools store is installed with

npm install @ngrx/store-devtools

Some people write the reducer before the action, but Duncan prefers to wrtie the action first. He says the actions serve like documentation for other developers.

He creates separate folders for actions and reducers. This is Duncan’s preference, and he has included a module on architectural considerations at the end of the Getting Started course that you should watch before started a serious ngrx project.

In the actions folder, Duncan creates two classes called LoadCompaniesAction and LoadCompaniesSuccessAction. He also creates a type called Action which is set to either one of these two actions.

Duncan warns that there is a lot of configuration involved with NgRx and you need to glue a lot of code together.

An alternative to NgRx which is a bit more terse is Ngxs. Both NgRx and Ngxs look like good solutions to me so I don’t have any strong opinion yet on which is best.

Duncan then creates a file called company.reducer.ts with a companyReducer function. This takes an action of type companyActions.Action which means it could either be a LoadCompaniesAction or a LoadCompaniesSuccessAction.

The function includes a switch statement which returns the action payload for the success action, or returns the current state as the default.

Duncan mentions some people like to use normalizr which is a more advanced technique.

Duncan updates the app.module.ts, importing the StoreModule, and adding StoreModule.provideStore({companies: companyReducer}) to the imports array. Note that from NgRX v4 and above, this should be StoreModule.forRoot({companies: companyReducer})

He says for bigger apps we would want to extract this out into another file and use combineReducers to create a single variable that can be passed into the provideStore method.

Duncan generates an interface file models/app-State.ts and gives it a property called companies of type Company[]

Once we have this we can change the type of the store object from Store<any> to the strongly typed Store<AppState>

Creating Effects

Duncan creates a effects directory with company.effects.ts inside it. We create a class called CompanyEffects, import both the Effect and Actions modules from ‘@ngrx/effects’ and apply the @Effect decorator (which comes from the effects library) to an observable loadCompanies$.

Duncan says NgRx heavily involves Observables. To learn more about RxJS and Observables see Deborah Kurata’s course RxJS in Angular: Reactive Development.

In this clip Duncan uses ofType and the map and switchMap operators. He says with switchMap we are switching from one observable to a new observable, and Lars adds that we are effectively switching contexts.

We call map within the function that is called by switchMap, and this returns the LoadCompaniesSuccessAction.

Duncan says this example is fairly representative of creating a new effect with NgRx.

Putting it all together

We see a problem with the app, because we haven’t registered our effect. In app.module.ts, add EffectsModule.run(CompanyEffects) to the imports array.

In ngrx v4 and up, this should be EffectsModule.forRoot([CompanyEffects])

After some messing around with import syntax, the app is all working again!

Recap

We’ve implemented the Redux pattern in an Angular app.

Store Dev Tools

Duncan recommends the Redux Devtools Extension for Chrome and Firefox.

In this clip we add the import to app.module.ts and add StoreDevtoolsModule.instrumentStore() to the imports array.

We then see time travel debugging in action. Duncan says this tool has had a big impact on his debugging experience.

Performance Improvements with Container and Presentational Components

Duncan says its possible to accidentally mutate the state in one of your reducers, and this can lead to change detection not working and your app breaking!

Duncan changes the ChangeDetectionStrategy to OnPush. This provides a performance improvement but you need to be careful if you decide to adopt this.

Tips and Testing

Again Lars and Duncan warn that you need to follow the recommended NgRx patterns and not get cute with your “optimizations” otherwise you could get into trouble.

Duncan recommends using separate reducers for each section of the data that is returned from the server, if the server is returning a large complex object.

We also see how to write unit tests. Refreshingly, Duncan starts by saying “JavaScript testing is a pain in the butt”, something I’ve never heard said before. Most blog posts say testing is easy in Angular, but as Duncan explains, you can end up writing a ton of code to mock out services before you actually get to write any tests.

Fortunately testing is much easier with NgRx because the only place to test is your reducer, and reducers are pure functions.

We see a unit test using the Jasmine framework, which is nice and clean. The form of it is:

describe — deleteCompanyAction
it – should delete a company

The test starts with two companies, deletes one of them and asserts that the result is the remaining company.

One complaint Duncan has about the ng test utility is the output is difficult to read.

We get introduced to Wallaby. This tool acts on your IDE to give your information about the status of your tests. It shows green indicators for passing tests and other colours for failing tests. Any test error is superimposed on the relevant line in your IDE.

Thanks to Duncan Hunter and Lars Klint for producing this course. Go check out the video for yourself here.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s