As a continuation of a previous post (where we learned how to use subscription), we will now implement that subscription to our HTTP requests to display the data on the page. Furthermore, we are going to use the advantage of Angular Lazy Loading, by using another module in our application – the owner module.
For complete navigation and all the basic instructions of the Angular series, check out the Introduction of the Angular series.
So, let’s start.
Create a New Module
So let’s start with the Angular CLI command for the module creation:
ng g module owner --routing=true --module app.module
This command does several things. It creates a new Owner module, it also creates a routing file for that module, and finally, updates the App module file:
CREATE src/app/owner/owner-routing.module.ts (248 bytes) CREATE src/app/owner/owner.module.ts (276 bytes) UPDATE src/app/app.module.ts (989 bytes)
Let’s inspect the owner.module.ts
file:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { OwnerRoutingModule } from './owner-routing.module'; @NgModule({ declarations: [], imports: [ CommonModule, OwnerRoutingModule ] }) export class OwnerModule { }
There are two small differences between this module file and the app module file. The first difference is that in the app module file we have an import statement for the BrowserModule
, and in the owner module file, we have an import statement for the CommonModule
. That’s because the BrowserModule
is only related to the root module in the application.
The second difference is that we don’t have the providers
array inside the owner module file. That’s because we should register all the services in the root module. That way components will inject the same instance of the service only once and you can keep the state in your service.
Of course, if we really want to register a service inside any child module, we could just add the providers
array. But, by doing so we cannot keep the state inside our service because every time we create a new instance of that component a new instance of a service is created.
Finally, we can see that this module imports the OwnerRoutingModule
from a separate file.
Owner Component and Angular Lazy Loading
Let’s start with the creation of the owner component files:
ng g component owner/owner-list --skip-tests
This command is going to create the required folder structure and it is going to import this component inside the owner.module.ts
file as well.
What we want now is, when we click on the “Owner-Actions” menu, to show the content from this component’s HTML file. So first, just for the testing purposes, let’s modify the owner.component.html
file by adding one paragraph (<p> tag):
<p>This is owner-list component page.</p>
After that, let’s modify the app-routing.module.ts
file:
const routes: Routes = [ { path: 'home', component: HomeComponent }, { path: 'owner', loadChildren: () => import('./owner/owner.module').then(m => m.OwnerModule) }, { path: '404', component: NotFoundComponent }, { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: '**', redirectTo: '/404', pathMatch: 'full' } ];
With the modified part of the code, we are configuring the app-routing.module
to load the owner module whenever someone searches for the http://localhost:4200/owner
endpoint. As we can notice, we are using the loadChildren
property which means, that the owner module with its components won’t be loaded until we explicitly ask for them. By doing this, we are configuring Angular lazy loading from the owner module content.
Now if we navigate to the Home page, we will get only resources from the root module, not from the owner module. And only by navigating to the owner-actions menu, we will load the owner module resources into the application. From the previous statement, we can see why is Angular lazy loading important for Angular applications.
Routing for the Owner Module
Now, to enable navigation to the OwnerList component, we have to modify the owner-routing.module.ts
:
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { OwnerListComponent } from './owner-list/owner-list.component'; const routes: Routes = [ { path:'list', component: OwnerListComponent } ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class OwnerRoutingModule { }
With this setup, we are exposing our OwnerListComponent
on the http://localhost:4200/owner/list
endpoint. Moreover, we are using the RouterModule.forChild
function and not the forRoot
function. This is the case because we should use the forRoot
function only in the root module of the application.
Now we have to modify the menu.component.html
file:
<div class="collapse navbar-collapse" id="collapseNav" [collapse]="!isCollapsed" [isAnimated]="true"> <ul class="navbar-nav me-auto mb-2 mb-lg-0"> <li class="nav-item"> <a class="nav-link" [routerLink]="['/owner/list']" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}"> Owner Actions </a> </li> <li class="nav-item"> <a class="nav-link" href="#">Account Actions </a> </li> </ul> </div>
After all of these modifications, we can run our app and click the Owner Actions
link. As soon as we do that, our new component will show up, and the link will get an active class style:
Now we know how to set up the routing for the child module, and for the component inside that module as well.
Subscription and Data Display
Let’s continue on.
When we navigate to the Owner Actions menu, we want to show all of the owners to the user. So that means when the owner component loads, the app automatically gets all the owners from the server.
We already have our Owner interface created (from the previous post) and we will use it here.
That said, let’s modify the OwnerListComponent
file:
import { Component, OnInit } from '@angular/core'; import { Owner } from './../../_interfaces/owner.model'; import { OwnerRepositoryService } from './../../shared/services/owner-repository.service'; @Component({ selector: 'app-owner-list', templateUrl: './owner-list.component.html', styleUrls: ['./owner-list.component.css'] }) export class OwnerListComponent implements OnInit { owners: Owner[]; constructor(private repository: OwnerRepositoryService) { } ngOnInit(): void { this.getAllOwners(); } private getAllOwners = () => { const apiAddress: string = 'api/owner'; this.repository.getOwners(apiAddress) .subscribe(own => { this.owners = own; }) } }
We have the owners
property with the and it is of the Owner array type. Next, we execute the subscribe function, which is going to populate that property with all the owners from the server. Using that owners
property to create our HTML page is what we aim for.
To accomplish that, let’s modify the HTML component:
<div class="row"> <div class="offset-10 col-md-2 mt-2"> <a href="#">Create owner</a> </div> </div> <br> <div class="row"> <div class="col-md-12"> <div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th>Owner name</th> <th>Owner address</th> <th>Date of birth</th> <th>Details</th> <th>Update</th> <th>Delete</th> </tr> </thead> <tbody> <tr *ngFor="let owner of owners"> <td>{{owner.name}}</td> <td>{{owner.address}}</td> <td>{{owner.dateOfBirth | date: 'dd/MM/yyyy'}}</td> <td><button type="button" id="details" class="btn btn-primary">Details</button></td> <td><button type="button" id="update" class="btn btn-success">Update</button></td> <td><button type="button" id="delete" class="btn btn-danger">Delete</button></td> </tr> </tbody> </table> </div> </div> </div>
We could split this html file into two components (the parent component: OwnerList and the child component Owner). But because we didn’t explain how to use child components, which we’ll do in the next posts, we are going to leave it like this for now.
We use some basic Bootstrap classes to create a table showing the owner’s data. Inside that table, we loop over all the owners with the *
ngFor
directive. Then by using interpolation {{}}
, we show owner properties on the page. For the dateOfBirth
property, we are using just the Date pipe | date: 'dd/MM/yyyy'
to format it the way we want to see it on a screen.
In our application, we are going to use the date format as MM/dd/yyyy, but here we are going to use dd/MM/yyyy just to demonstrate the way to change the format with pipes without too much effort.
Now, we can start our server app, which you can find on this GitHub repo. Once we start it, we can run our Angular app and navigate to the Owner Actions
link:
Conclusion
By reading this post we have learned how to create a new module and what imports to use. Additionally, we’ve learned the way to configure Angular lazy loading and how it can help our application.
Also, now we know how to execute HTTP requests with a subscription and display result data on the page, and the way to reformat our date when displaying it.
In the next part of the series, I am going to show you my way of error handling while sending HTTP requests. Moreover, we are going to create a Details page for the single owner.