If you missed any of the previous articles, you can read them here:
In this third part of the tutorial, I am going to cover the topics give below.
- Creating Routing
- Add
- Validation
- Delete
- Update and more
At the end of the article, you will find the link to the source code on GitHub, so feel free to play with the code yourself.
In part 1, I created RESTful API, using node.js and MySQL. In part 2, I discussed the read operation and also how to create custom filter pipe etc.
Now, in this article I am starting from routing.
Creating Routing
Angular2 routing is all about the changing state of your Application and loading different components which depend on the URL that the user enters. Angular 2 first parses the URL entered by the user, identifies the routes and then finally loads the suitable component.
How does routing work?
First, I am creating the router array.
- [code language=”typescript”]
- app.routing.ts
- import {
- Routes,RouterModule;
- }
-
- from '@angular/router';
- import {
- TasksComponent;
- }
-
- from './tasks/tasks.component';
- import {
- AddtasksComponent;
- }
-
- from './tasks/addtasks.component';
- const routerRoutes=[ {
- path'',redirectTo'/allTask',pathMatch'full';
- },
- {path'allTask',componentTasksComponent;
- },
- {path'addTask',componentAddtasksComponent;
- }
-
- ];
- export const routes=RouterModule.forRoot(router);
- [/code]
Thus, in the code above, I had imported Routes and RouterModule from @angular/router and created one const array, which is named as a router. Inside the array, I created the routing paths. For example, if the user does not enter anything in the URL, which is
http//localhost4200/. It will redirect to ‘/allTask’ and it will load the tasks.component.
After creating the routing file, it must be declared in imports array in app.module.ts
- [code language = ”typescript”]
- imports[
- BrowserModule,
- FormsModule,
- HttpModule,
- routes
- ], [/code]
Now, the third step for routing to perform in Angular 2 is setting up the router-outlet in app.component.html, which is the route component of my project.
- [code language = ”html”] < router - outlet > < /router-outlet> [/code]
Now, on loading of the root component, it will directly go to app.routing.ts file and depending on the URL requested by the user, the component will be loaded..
Now, we need routing on each and every page. Thus, for my convenience, I am creating one component as a header.component in which I will create a menu for my project. I am using Bootstrap to design the menu.
Header.component.html - [code language=”html”]
-
- <nav class="navbar navbar-inverse">
- <div class="container-fluid">
- <!-- Brand and toggle get grouped for better mobile display -->
- <div class="navbar-header">
- <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
- <span class="sr-only">Toggle navigation</span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- </button>
- <a class="navbar-brand" routerLink="/allTask">CsharpCorner</a>
- </div>
- <!-- Collect the nav links, forms, and other content for toggling -->
- <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
- <ul class="nav navbar-nav">
- <li class="active">
- <a routerLink="/allTask">Task
- <span class="sr-only">(current)</span>
- </a>
- </li>
- <li>
- <a routerLink="/addTask">AddTask</a>
- </li>
- </ul>
- </div>
- <!-- /.navbar-collapse -->
- </div>
- <!-- /.container-fluid -->
- </nav>
- [/code]
In HTML given above ,
Focus on
<a routerLink="/addTask">AddTask</a>. Now, as Angular2 has done all routing locally, so we will be using router link instead of href.
Add New Task
In this demo, I am using two way data binding for the add operation. You can get an idea about data binding from
here.
addtasks.component.html - [code language=”html”]
-
- <div class="row">
- <app-header></app-header>
- </div>
- <div class="container">
- <form (ngSubmit)="taskSubmit()" #addform="ngForm">
- <div class="form-group">
- <label for="id">Id</label>
- <input type="number" [(ngModel)]="model.Id"
- name="id"
- class="form-control" id="id"
- required #id="ngModel">
- </div>
- <div [hidden]="id.valid || id.pristine"
- class="alert alert-danger">
- Task Id is required
- </div>
- <div class="form-group">
- <label for="name">Task</label>
- <input type="text" [(ngModel)]="model.Title"
- name="title"
- class="form-control" id="name"
- required #title="ngModel">
- </div>
- <div [hidden]="title.valid || title.pristine"
- class="alert alert-danger">
- Task Title is required
- </div>
- <div class="form-group">
- <label for="power">Status</label>
- <select class="form-control" id="status"
- [(ngModel)]="model.Status" name="status"
- required>
- <option *ngFor="let s of status" [value]="s">{{s}}</option>
- </select>
- </div>
- <button type="submit" class="btn btn-default form-control" [disabled]="!addform.form.valid" >Add Task</button>
- </form>
- </div>
- [code]
In the above html, I called the <app-header></app-header> component for the menu which I had created previously and also created #addform variable which is the reference to the <form > itself. On Clicking of button I checked for form’s state and whether it is valid or not. If all the validations inside the form are validated then the form will be valid, otherwise the form will be in an invalid state. Depending on the form’s state I am enabling the button.
- [code language=”html”]
- <button type="submit" class="btn btn-default form-control" [disabled]="!addform.form.valid" >Add Task</button>
- [/code]
As I said I am using two way data-binding for add operation, I will create the model object on addtasks.component.ts and bind it with different controls so that when I change the values from controls it will automatically change in the model.
- [code language=”html”]
- <input type="number" [(ngModel)]="model.Id"
- name="id"
- class="form-control" id="id"
- required #id="ngModel">
- [/code]
So with the [(ngModel)]=”model.Id”, when I am changing the value in input box it will also reflects in model object in addtasks.component.ts file.
I had used dropdown for Status field (done or pending), so I will create an array of string in typescript file and loop through it and bind it to html page.
- [code language=”html”]
-
- <select class="form-control" id="status"
- [(ngModel)]="model.Status" name="status"
- required>
- <option *ngFor="let s of status" [value]="s">{{s}}</option>
- </select>
- [/code]
addtasks.component.ts - [code language=”typescript”]
- import { Component, OnInit } from '@angular/core';
- import { Router } from '@angular/router';
- import { TaskdataService } from '../shared/taskdata.service';
-
- @Component({
- selector 'app-addtasks',
- templateUrl './addtasks.component.html',
- styles []
- })
- export class AddtasksComponent implements OnInit {
- statusstring[]=[
- 'done',
- 'pending'
- ];
- model = {Id'',Title'',Status'pending'};
- constructor(private _taskdataTaskdataService,private _routerRouter) { }
- ngOnInit() {
- }
- taskSubmit()
- {
- this._taskdata.addTask(this.model)
- .subscribe(
- (dataany)=>{
- console.log(data);
- this._router.navigate(['/allTask']);
- },
- function(error){
- console.log(error);
- },
- function(){
- console.log('complete');
- }
- );
- }
- }
- [/code]
Here in above code as I said i created the Status array of type string and model object which can hold Id,Title,Status.
On click of add task button I am calling the taskSubmit() function inn which I am calling addtask method which I created in taskdata.service.
Subscribe method will take three arguments first is on success, second on error, third on complete.
Delete Task
Now for delete task ,I will simply add one button inside the tasks.component.html which I created
previous article. - [code language=”html”]
-
- <button (click)='deleteStatus(item)' type="button" class="btn btn-default" aria-label="Left Align">
- <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
- </button>
- [/code]
Here I create the click event for delete button on which I am calling the deleteStatus method.
- [code language=”typescript”]
- deleteStatus(itemTask){
- this._taskdata.deleteTask(item.Id)
- .subscribe(
- (dataany)=>{
- this.allTasks.splice(this.allTasks.indexOf(item),1);
- },
- function(error){
- console.log(error);
- },
- function(){
- console.log(‘complete’);
- }
- );
- }
- [/code]
On success I am simply removing the record from the array as page will not post back.
Update Task Now on update I simply created the toggle button i.e. it will change the status to done or pending.
- [code language=”html”]
-
- <button (click)='updateStatus(item)' type="button" class="btn btn-default" aria-label="Left Align">
- <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
- </button>
- [/code]
Here I create the click event for update button on which I am calling the updateStatus method.
- [code language=”typescript”]
- updateStatus(itemTask){
- this._taskdata.editTask(item)
- .subscribe(
- (dataany)=>{
- if(item.Status=="done")
- {
- item.Status='pending';
- }
- else
- {
- item.Status='done';
- }
- },
- function(error){
- console.log(error);
- },
- function(){
- console.log ('Edited successfully');
- }
- );
- }
- [/code]
Summary
We covered a lot in this tutorial. Let’s just summarize it.
- Routing
- Validation
- Add
- Delete
- Update and more
There is a lot more to come in the next tutorial (Multiple delete,file upload,pagging). So, stay tuned for more.