NGRX made easy — a tutorial to add NGRX in any project <5 minutes

In this tutorial, I’m going to demonstrate the fastest way to get full NGRX functionality into your application, utilizing the Dynamic NGRX library.

We’re going to build a very simple “ToDo” app. This article is for developers who are interested in using NGRX, but might be scared away by the sheer volume of boilerplate required to get started, developers who are sick of all the boilerplate and looking to simplify their lives, or developers that just want the easiest way possible to implement NGRX into their project.

If you were to approach the Todo list with a traditional NGRX method, you would have to do something like create todo.reducer.ts, todo.actions.ts, todo.selectors.ts , build a Todo interface, and then configure and add the NGRX store module to your project. And that’s just to get the basic functions working. Then, if you wanted to persist the data, you’d still need to add todo.service.ts to handle your http requests and todo.effects.ts plus updating your actions file and reducers to handle all the new functionality. It makes me tired just thinking about it!

It’s a lot to just do something as simple as building a checklist, and frankly, sometimes rather overwhelming when you just want to get started.

That’s where Dynamic NGRX comes in. This library greatly simplifies this process by virtually eliminating all of the boilerplate, and allowing for the full NGRX functionality with a just few lines of configuration.

This tutorial assumes you’ve already set up the Angular CLI on your machine, and are familiar with its basic usage. So, without further ado, let’s get started.

Set up the project

Start by creating a new project.

ng new ez-ngrx

Hit “N” for routing and “SCSS” for styling. Your project will get initialized, and change to that directory

cd ez-ngrx

Now we need to install the package dependencies, which includes all of the NGRX libraries. We’ll also install the NGRX localstorage module for data persistence and logger module for development purposes. Yes, there are a lot of dependencies, and man, this would be super daunting if we actually had to work with all of them. Thankfully, Dynamic NGRX will take care of that for us.

npm i @ngrx/effects @ngrx/entity @ngrx/router-store @ngrx/store @ngrx/store-devtools ngrx-store-localstorage ngrx-store-logger --save

We’re also going to install Angular Material and Angular Flex because they make it really easy to get something that looks pretty good with almost no effort.

npm i @angular/material @angular/cdk @angular/flex-layout --save

Finally, add the Dynamic NGRX library.

npm i dynamic-ngrx --save

Alright, now we’re ready to get started. If you run

ng serve

in your console, and navigate to “http://localhost:4200" in your browser, you should see the default project page like this:

Layout the Framework

Let’s start by importing the modules to the project. Open up app.module.ts and import the required modules to the project as follows:

Then, we need to enable the Angular Material theme styling. Create a file called src/theme.scss and copy the following

By default, Angular Material doesn’t define a theme, so we need to tell it what theme and colors to use in our project. It comes with handful or predefined ones, but we’re just going to create our own.

Now we need to import the Angular Material theme settings into our project. Open the src/styles.scss file generated by the Angular CLI, and add the following to it

I always throw in the margin around cards, because for some reason the margin is set to 0 by default in Angular Material and it always looks bad if you don’t.

Then, open up the app.component.html file and add the following

If everything is working correctly, your browser should now look like this

Thus far, all we have done is imported the Angular Material theme library, done some minor formatting with the card, and created the basic layout for the todo list.

Adding Logic to the Component

From here, we’re going to add some logic to the component and make our list to start populating some “Todo’s”.

The first thing we’re going to do is get a way to collect the text from the input field. With Angular, there are at least 3 different ways I can think of we could use to make this happen (i.e. template driven form, reactive form and using an element reference). We’re going to use the element reference, because I also want to just make it add the “Todo” as soon as you hit “Enter” in the input field without having to add a button.

Go back into the app.component.html file, and add a template variable and keyup listener to the input field.

There are two main things we’ve done here.

First, we added#todoInput and (keyup) to the input element. #todoInput assigns a variable to the input field, which we can either access directly in the HTML template, or we can access it from the component controller. The (keyup) property binds a listener to the input field, and allows us to attach a method to the listener, that will get called after every “keyup” event from the input field.

Second, we added a button element to the action list that will populate the action list with the “Todos” we add to our list. We’re not going to do anything too fancy yet with the list, we’re just going to iterate through the “Todos” that get added to the list.

I’m going to quickly add an interface for the Todo entity. For simplicity’s sakes, I’ve just added it to app.module.ts but you can add it wherever you’d like, as some people like to put it in their own models file for organization.

Let’s now get the data from the input field in the component controller. Open up app.component.ts and add the following.

First, we’ve added the @ViewChild decorator which allows us to access the template variable, todoInput , which is the input element #todoInput we declared in the earlier step. We can now access this element within our component controller.

Second, we’ve added an array “todos” that will hold the elements to be iterated in the template.

Third, we added an addTodo method that receives a KeyboardEvent for input. Every keyboard event has a numeric keyCode associated with it. The only one we care about is when the user hits “Enter”, which has a keyCode of “13”. We’re going to ignore the rest of the keyup events.

When “Enter” is pressed, we’ve imported a quick library to generate a unique ID for the todo ID, and then we grab the text from the input element, and push it to the todo array and then it resets the input field value.

Finally, we’ve added a removeTodo method that will remove a Todo from our list when we click on it.

With this functionality in the controller, if you go back to the browser, your Todo list should work. You should be able to type into the input field, hit enter, and see it show up in the Todo list. You should also be able to click on any of the todo’s, and they will be removed.

Bring in NGRX

Alright, so this is awesome and all, but now it’s time for us to add the functionality you’ve all come here for — how to add NGRX in the simplest manner you’ve ever seen.

First things first, let’s go back and add Dynamic NGRX to the app.module.ts file.

There are two things we’ve added here. First is the config object. The two properties we have are entities and providers.

The entities property is a collection of entities we want to add to the application. To start with, we just add a single “Todo” entity to the collection.

This is one of the most magical parts of Dynamic NGRX, as this is all you have to do to add another entity class. With conventional NGRX, if you wanted to add a “Todo” entity to your store, first you’d have to define the reducer state, and add the reducers, then create the actions you wanted to add, and then define some entity selectors. Now, with Dynamic NGRX, all you have to do is add an object to the entities collection and you’re off to the races. We’ll see how to utilize it in your application shortly.

The second property, providers is honestly just there to resolve an issue that will pop up with Angular’s AOT compiler. At a future date when we add data services to our application, we’re going to need to declare some providers here. However, if it’s empty and we don’t include the property, Angular will throw an error. I’ve spent a ton of time fighting this one, and have yet to be victorious in removing that property. I’m hopeful someone down the road can help me figure out how to make it not necessary. I’ll do a future tutorial where we’ll use that property, but for now, just declare an empty array.

Once we have our store configuration defined, we pass that configuration object to the DynamicNgrxModule root method to initialize it.

Aaaannddd… that’s it. That is literally all you have to add to get access to the full library of NGRX functionality. Through those few lines of code you added, you now have reducers, entity selectors, actions, effects, observables, etc.

Where’s my Staples “That was easy” button?

Let’s connect it up to our component now. Update your app.component.ts with the following

So there are a handful of changes here to call out, so follow along with me, one step at a time.

The first change is we’re importing the DyanmicFacadeService and the NGRX Store. I’ll discuss more about the store later, but the DynamicFacadeService is basically a factory that generates an instance of a facade tailored around the entity you have defined. If you aren’t familiar with facades, read here for more details. They’re basically a single service that you can use to interface with to access all the NGRX functions. There’s a lot of debate over the benefit of facades, with some definite pros and cons, but personally for the sake of simplicity and speed of development, I’m a huge fan of them and Dynamic NGRX utilizes them exclusively.

this.todoFacade = this.dynamicFacadeService.getFacade<Todo>(‘Todo’);

Once we import the DynamicFacadeService, we call the getFacade function, pass in an interface describing the entity, the name of the entity, and it returns a facade that will be the way we’ll interact with NGRX.

this.todos$ = this.todoFacade.entities$;

We then use the Todo facade we created to access the entities$ property, which will return an observable array of all the Todos in the store. This is just one of the many properties on the Todo facade we can access. Other common properties include loading$, loaded$, selectedEntity$, etc. which become really useful as we get into more advanced functionality with data providers and selecting specific entities.

You’ll note that we are importing the NGRX store object. We utilize this in the addTodo method, where we use the store dispatch method to dispatch new actions, like adding a new Todo.

Now you might be thinking, “Why do we have to import the store and dispatch a new action? Why don’t you just import the store to the facade, and add an ‘addOne’ method that automatically dispatches an [Add One] action?” Well, as Sam Julien discusses in his excellent article discussing the pros and cons of facades, there comes some traceability issues later down the road for debugging, as it becomes difficult to trace where the [Add One] action was dispatched.

this.store.dispatch(this.todoFacade.actions.addOne(todo));

Instead, we use the facade to generate the action itself. The addOne method takes an instance of the entity, and will dispatch all the necessary plumbing to add the object to the NGRX store. The removeTodo method has been updated to follow a similar pattern.

One the action has been dispatched, out entities$ observable will return the updated value, and then update the view. Speaking of which, let’s update the view to use this new observable.

The main change is we modified the ngFor iterator to use the new todo entity observable, and added the async pipe.

If all is well, your application shouldn’t look any different, but there’s a whole lot more going on now.

You should now be able to add Todos to your list and remove them as before. However, if you have the Redux Devtools plugin installed, you’ll see there’s a lot more going on in the background in your developer console.

Awesome! You now have a fully functional NGRX todo list, and you created it with what I can only hope was a minimal amount of pain to get up and running.

Offline Support

The only thing left that’s annoying is your Todo list completes itself every time you refresh your browser (the data doesn’t persist and the list resets).

Fortunately, Dynamic NGRX made this really easy for you to handle. All you have to do is go into your app.module.ts file and modify the config object to enable offline sync. Once you add that property, all of your Todos should automatically persist through page reloads.

I’ve uploaded the project file to Github for your reference.

If you’ve enjoyed this tutorial, please check out the next one — it demonstrates how to connect up a back end service without having to use any effects.

This concludes my first tutorial on making NGRX easy using Dynamic NGRX. If you liked it, please give me a clap or share your thoughts in the comments. Thanks for the read!

Chief of Staff @ The Future of Work Studios. Husband. Father. TFA. McKinsey & Co. 3X startups. Entrepreneurship, leadership and self-actualization enthusiast.