Angular 2 Modules, Components, Redux, Routes and More!


Back in July…June? Some time ago I started a series on making a gradebook with Angular 2. It was going OK until the Angular team decided to make, for the greater good, some groundbreaking changes. It was enough to make me abandon the project and move on to other things. A short while ago I wanted to give the other devs on my team an intro into the tech we will be using on an upcoming project. Thus, my login component tutorial was born…

What I’ll Go Over

This little guide will provide an intro to the following concepts, modules, routes, route guards, services and redux. This is not meant to be an in-depth guide, more of a intro into the concepts. Most people do this through the always popular Todo app But those tend to be more involved that I want to get into so instead I’ll be making a simple login and dashboard page. 

How it will work

The whole tutorial can be found in here in on my GitHub page. Each step in the tutorial will reference a commit so that you can follow along. With that, let’s begin!


Step 1 – Creating a project


This has become so incredibly easy since the time of yester-march. 

  1. Install the latest node. 
  2. Install the Angular 2 CLI   — ‘npm install -g angular-cli’
  3. Create a new project —  ‘ng new login’

Boom. Done

You can read all about it here but essentially it creates a basic folder structure from which I will build upon. 

With the project built, you can run the start command ‘ng serve’ or the npm script found in the package.json file ‘npm start’. Both do the same thing. When it finishes doing its thing, you can navigate to localhost:4200 and you should be greeted with…


Step 2 – Login Module Structure


Don’t know what a module is? Go here. Don’t want to go there? Allow me to copy and paste

Angular Modules help organize an application into cohesive blocks of functionality or features.

Got it? Good!

First I want to create a folder called modules. You can structure your project however you want, this is just how I do mine. The modules folder will reside under the app folder. Inside of the modules folder, I’ll create a login folder. Inside of that one, I’ll create a login component and a login.module file.

How do I make the component? I’m glad you asked! I use the CLI like so.

Open command prompt/shell and navigate to the login folder that was just created and execute the following

‘ng g c login’

“ng” is the base command. “g” is shorthand for generate. “c” is shorthand for component. “login” is the components name.

Next, I will create a login.module.ts file. 

After all is said and done, the folder structure should look like this.


Step 3 – Login.Module.ts

Github -Step 2 and Step 3 are the same commit in the case.

Before I work on the login component, I want to setup the login.module file. The point of the file will be to expose the login component to the outside world. This way, anyone who imports the module can use the component. This is the same way that components libraries like Material Design work

Pretty simple.

To test that everything works, I want to have my main app.module import my login module. How?

You can see that I first import the LoginModule and then add the import the imports array in the NgModule declaration. To test that this worked you can add your login component to the app.component.html like so.


I should point out that the default name for a component that is generated with the CLI is “app”- {whatever you named the compoent} But I changed my to diveraj-login. This was done in the login component like so

To save yourself the headache of doing this for everything…. Open the angular-cli.json file in the project and find the line with project “prefix”. The default is, you guessed it, “app”. I changed mine to “diveraj”

If you’ve done everything correctly, when you refresh the page you should see…

Hmm, I guess the login works. 

Step 4 – Routes

Github — If you want, and you really should, you can read the Angular 2 routing doc here.

So you say you want your login page to be in the “/login” subdomain? Fine, be difficult.

First, we want to set up routing on the app level. To do so, you’ll create a routing.ts file and place in on the same level as the app.modules.ts file. Here’s mine routing file.

The important bit is the Routes array. Mine says when “login” is navigated too, redirect to the login route. What’s that? Don’t worry, I’ll go over that next. But if wanted to you could import the login component like so.

Ohh I named mine, app.routing.ts

Notice how the “redirect” property has changed to “component” and the “login” string has changed to the imported LoginComponent. 

So why you do the first option? Like all things it depends. Doing the first option allows your feature module to set up its own routing table. This why if you feature module want to add subroutes, it could. It also decouples the app.module from the login module since the app routing no longer has to import the LoginComponent. 

Now I want you to take a note of the last line.

This tells Angular 2 that this routing table will be the base for the entire app.

Now that we have to load our new routing table in app. Since it is just another module,we just import it into the app.module

Next, we will do the exact same thing for our login module.

Create the routing file on the same level as login.module.ts

Here’s mine. 

You’ll notice that this time, I specified the Login Component. That’s because we want this routing table to load the LoginComponent. I also left out the forRoot. Instead, I used the “forChild”. This is how you register a route for a feature module.

Next, we import the LoginRouter into the login.module

Annnnddddd…. Not quite done.

We have yet to specify the router-outlet!

What’s a router-outlet? It’s an Angular 2 Tag that goes in the HTML. When the URL matches something in your routing table, the component that matches that route will be insert AFTER the tag

If you were to look at the HTML after you naviated to “/login”, it would look something like this


So let’s update the app.component.html file.


Now we test it!


Step 5 – Dashboard


Now, we are going to basically copy the login module. To save time, I won’t go over the making over it. It’s an exact copy of the login module except instead of ‘login’ its ‘dashboard’. You can always refer to the linked GitHub if you get confused.

After we have the dashboard module created, we’ll import it into the app module.


Don’t forget to add it to the routing table


Now we test it.


But you know, I don’t think I like having to navigate to “/dashboard”. No, I rather have the dashboard be on the root level. Let’s change the dashboard.routing.ts file to make that happen.


And remove the one from the app routing table.


And test again


But wait… I’m not logged in! I shouldn’t be able to get to the dashboard!

Step 6 – Route Guards

Github — You can read about route guards here

Quick Route Guard definition – A route guard, once assigned to a route, can either stop the route from occurring or allow it to happen. In this example, I want to stop a user from being able to go to the dashboard if they haven’t logged in. 

A Route Guard begins its life like any other service. So let’s make one!

Using the CLI command –  “ng g s route-guard”

Tip! You can place this anywhere you like. For now, I just placed it on the same level as the app.module. 

Simply put, a route-guard is a a  service that implements the CanActivate component from the ‘@angular/router’. Let’s take a look at how I implemented it.

You can see that I am implementing the CanActivate component and overriding the canActivate function. The function itself takes in a route and state object and returns a boolean. Each gives details about the well, the name of the variable should be obvious. If not… read the link above! In any case, I’m not using them from this example.

The return boolean determines what should happen. True lets the user navigate to the route, false prevents them. 

As a helper to the CanActivate function I created a isAuthenticated function that will execute some logic that determines if a user is logged in. But for now, it just returns false.

So if the user is authenticated, canActivate returns true and the user is directed to the dashboard. Otherwise, I use the route service, which I added in the construction, to navigate to the login page. 

With my route-guard done I need to add it to the app.model so it is available to the other components.


Next, I will go the dashboard.routing file and added the guard like so.

The observant person will see that the service is inside of an array… You can have multiple guards assigned to a route.

Next we test the guard by simply refreshing the page. Since I have the guard set to be false it should redirect you to the login page.

Now that we have a guard in place, we should probably make the login page more function.

Step 7 – Login Service


Frist thing we want to do is modify the login HTML in include a form… no not really. This is all about the lazy. Instead, I am going to add a button.

When clicked, the button will execute the login function in the login component.


Next we want to create a login service that our login function can call. First we create a “services” folder under the login module folder.


Inside of my new services folder, I create my login service like so

“ng g s login”

In the service we will creating a authorized variable that will store whether a user is logged in or not. Then we will create a login function that will set that variable to true and then navigate to the dashboard. 


Next we will  import the new login service and add it to the providers array of the login.module


Then, we modify the login component to inject the service by adding to the constructor. This allows the login component to call the login function in the login service


If you test this now, you’ll see that when the button is clicked, you’re still stuck on the login page. Why? Because we haven’t changed the route-guard yet!

Here I injected the login service and changed my isAuthenticated function to return the public “authorized” variable stored in my login service. Now we can test it again to see if it works.

Click the button!


You could stop here and start to expand out your app. But storing data in a service like I’m doing with my “authorized” variable is going to get very hairy very quickly. One possible solution to this problem is….

Step 8 – Redux

GitHub –  Don’t know what Redux is? Go here. It’s a long read, but worth it.

Well, let’s dive in. I’m going to assume you read the link above and understand the basics. If not, read the link above.

First thing we have to do is find a library that implements Redux for Angular 2. Ohh look I found one for you! NgRx

The library we want is the one called ngrx/store. The rest do some cool things so it’s worth poking around their GitHub page when you get time. Anyhow execute the following to install the library.

npm install –save @ngrx/core @ngrx/store

Why @ngrx/core? Because the @ngrx/store has it as a dependency. Duh.

After NPM does its thing, the two NgRx packages will be added into your node_modules folder. And because we did a “–save”, the package.json file will have been updated to include the two libraries. 


Let’s now create our our first reducer!

I’m going to add this reducer to the login module so I’ll create a reducers folder under the login module directory. Inside my new folder, I’ll create a login.reduce.ts file.


This is our basic reducer. It imports the @ngrx/store component and then exports our LoginReducer.


This line initializes the reducer to a default state. In our case, the default state is an object with an authorized property that is set to false.


At a basic level, a reducer is just a function that returns a state. When executed the reducer takes in an action. An action has a type which acts as an identifier for what kind of action we want to do. To identify the type, we switch and execute some code based on that type. You don’t have to use a switch, feel free to make a hung if/else tree. Or don’t, because your co-workers will hurt you gravely if you do. But the choice is yours!

No matter how you do it, a reducer must have a way to return the default state. Hence the default statement in the switch. But our app needs a way to modify the login value, so we’ll create a “login” case. 

As you can see, I added a “login” case. With Redux, you ALWAYS return a new state. You never return a mutated state. This prevents Race conditions from occurring. Here I am setting the authorized state to be whatever I pass in via action.payload.

Next we’ll need to modify the app.module file so that we can use our new store.

To make the reducer available we have to call the “provideStore” function on the StoreModule and pass in a configuration object. The object is a key value pair. The key being what you want to name the reducer and the value being the actual reducer. 


In this case I named my LoginReducer, “login”. I’ll explain why you need to name it later.

Now let’s modify the login service to use our new store.

First, we import the store and inject the store service.

We can then use the store service to dispatch an event. The event has a type and a payload, which lines up with the type and payload object from our store!

Our store is expecting a type of “login” and a payload that is a boolean. Hence the line.


Now that our service is interacting with the reducer, we’ll need something to read data from the reducer. What would need to do that? Our route-guard of course!


Our newly updated route-guard imports the store and then injects the store service. I then call the “select” function on the store service. The function takes in a string that references the store you want to retrieve. You’ll recall that I named my store “login”, so that is what we passed in. 


The select function will then return an observable of the reducer I selected. Our Observable in hand, all we need to do  is to subscribe to it. 

Now, whenever something modifies our store, this function will fire! 

Finally, we can chang the canActivate function to use our new locally variable. Then, we test!

Good. Good. 

Step 9 – Redux Models


Hmm, if you recall, the initial state of reducer was an object, but that’s not very TypeScripty. Let’s change it so that it uses a model.

Just like the services and reducers, we will create a models folder.


Inside the models directory, we add the “auth.model.ts” file. Our model will just mimic what we are currently using in our reducer.

Now we just need to update the login reducer, login service, and route-guard to use the new AuthModel model.

First the reducer.

Next, the service

Finally, the route-guard

Now we test and make sure we didn’t break anything. But I still think we can improve on a few things.


Step 10 – Redux: A better way? Multiple Reducers


Remember when we imported the reducer into the app.module? Imagine if we had 15 reducers in our login.module. It would become quite the pain in the Angular if we had to do that 15 times, so let’s do it a better way.

In the reducers folder, under the login module, we’ll create a “reducers.ts” file.


The purpose of the file will be to gather up all of the login reducers and export them as a single object. Let’s take a look how to do that.

I know, it’s just 1 reducer you say. Well, this is what it would look like if I made up 2 more!


Now we will use that object in our app.module.


Look at how much cleaner that looks! Wonderful. Let’s do a quick test… yep… still works!


Step 10 – Redux: A better way? Actions

GitHub  — You can read about Actions here

Whenever you call the store.dispatch function, the data that you pass in is an Action. For example…

The JSON object is your action. An action has a type and payload, “x” and Y”. But the same way a store should use a model for it’s state, the dispatch function should use an Action Generator. This way, if you need to modify an Action, you can do so in one place. So let’s make one.

First, we make an action folder and a “login.action.ts” file.


Inside the file we will define the Action Types and Actions Classes. 

The ActionTypes constant is used by other components to help identity the available Actions a reducers has. Our reducer only has a single action, “login”.

We then create a class called LoginAction that implements the Action component that we imported from @ngrx/store. Because we implemented an Action, our class needed to define the type variable and payload type. 

With our new LoginAction class we can create a new Action like this.

Which will return an Object that looks like this.


Now we can update our reducer to reference the ActionTypes.

You can see that I replaced the ‘login’ string in the switch statement with the new ActionTypes login property. 

Next, we’ll update the login.service

And here I changed the dispatch parameter to use my new LoginAction.

We do another round of test to make sure it works and boom goes the dynamite.


Holy mother that was a lot. Here’s a quick rundown of what we just did..

  • Project Generation with the Angular 2 CLI
  • Creating a Component with the CLI
  • Create a Login Feature Module
  • Creating a Route
  • Creating a Dashboard Feature Module that acted as our main page
  • Added a Route-Guard to the Dashboard so only authorized users could access it
  • Created a Login Service
  • Added a Redux implementation NgRx
  • Created a Login Reducer
  • Created an Authentication Login Model
  • Had the Login Service and Route-Guard use the Login Reducer
  • Created Login Actions from the Login Reducer

I mean, look at that list! It’s huge! Hope this help and thanks for reading!


Facebooktwittergoogle_plusredditpinterestlinkedinby feather