Crud in angular2 part2

Hello Readers,

This is part3 of CRUD(create,read,update,delete) operations in Angular2.if you missed any part you can read it here.

Part 1-How to Create RESTful API using Node.js and MySQL

Part 2-working with read operation in angular 2/Pipes/http

In this third part of the tutorial, I am going to cover the following topics:

  • 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 had created restful api using node.js and mysql and in part 2 I had discussed the read operation and also how to create custom filter pipe and etc…

Now in this article I am starting from routing.

Creating Routing

Angular2 routing which is all about the changing state of your application, loading different component depending on the url user enters. Angular 2 first parse the url entered by user  then identify routes and then finally loads the suitable component. 

How routing works?

untitled

So first I am creating the router array.

app.routing.ts

import { Routes,RouterModule } from '@angular/router';
import { TasksComponent } from './tasks/tasks.component';
import { AddtasksComponent } from './tasks/addtasks.component';

const router:Routes=[

{path:'',redirectTo:'/allTask',pathMatch:'full'},

{path:'allTask',component:TasksComponent },

{path:'addTask',component:AddtasksComponent }

];

export const routes=RouterModule.forRoot(router);

So here in above code I had imported Routes and RouterModule from @angular/router and created one const array named as router. Inside the array I had created routing paths. For example if user will not enter anything in url just like http://localhost:4200/ it will redirected 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


imports: [

BrowserModule,

FormsModule,

HttpModule,

routes

],

Now 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.


<router-outlet></router-outlet>

Now on loading of root component it will directly go to app.routing.ts file and depending on the url requested by user component will be loaded..

Now we need routing on each and every page. So for my convince I am creating one component as header.component in which I will create menu for my project. I am using bootstrap for designing menu. 

Header.component.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>
&nbsp;

<!-- 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>

Now in above html ,

Focus on  <a routerLink=”/addTask”>AddTask</a> , now as angular2 done all routing locally so that we are using routerLink instead of href.

Add New Task

In this demo I am using two way data binding for add operation. You can get idea about data binding from here.

addtasks.component.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>
&nbsp;
<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>

In above html ,I called the <app-header></app-header> component for menu which I had created previously and also created #addform variable which is the reference to the <form > itself, On Clicking of button I had checked for form’s state whether it is valid or not? If all the validation inside the form are validated then  form will be valid otherwise form will be in invalid state. Depending on the form’s  state I am enabling the button.


<button type="submit" class="btn btn-default form-control" [disabled]="!addform.form.valid" >Add Task</button>

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.


<input type="number" [(ngModel)]="model.Id"

name="id"

class="form-control" id="id"

required #id="ngModel">

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 a array of string in typescript file and loop through it and bind it to html page.


<select class="form-control" id="status"

[(ngModel)]="model.Status" name="status"

required>
<option *ngFor="let s of status" [value]="s">{{s}}</option>
</select>


addtasks.component.ts


import { Component, OnInit } from '@angular/core';

import { Router } from '@angular/router';

import { TaskdataService } from '../shared/taskdata.service';

&nbsp;

@Component({

selector: 'app-addtasks',

templateUrl: './addtasks.component.html',

styles: []

})

export class AddtasksComponent implements OnInit {

status:string[]=[

'done',

'pending'

];

model = {Id:'',Title:'',Status:'pending'};

constructor(private _taskdata:TaskdataService,private _router:Router) { }

ngOnInit() {

}

taskSubmit()

{

this._taskdata.addTask(this.model)

.subscribe(

(data:any)=>{

console.log(data);

this._router.navigate(['/allTask']);

},

function(error){

console.log(error);

},

function(){

console.log('complete');

}

);

}

}

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 ,In 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.

screenshot-105screenshot-107

 

Delete Task

Now for delete task ,I will simply add  one button inside the tasks.component.html which I created previous article.


<button (click)='deleteStatus(item)' type="button" class="btn btn-default" aria-label="Left Align">

<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>

</button>

Here I create the click event for delete button on which I am calling the deleteStatus  method.


deleteStatus(item:Task){

this._taskdata.deleteTask(item.Id)

.subscribe(

(data:any)=>{

this.allTasks.splice(this.allTasks.indexOf(item),1);

},

function(error){

console.log(error);

},

function(){

console.log(‘complete’);

}

);

}

On success I am simply removing the record from the array as page will not post backed.

Update Task

Now on update I had simply created the toggle button i.e. it will change the status to done or pending.


<button  (click)='updateStatus(item)' type="button" class="btn btn-default" aria-label="Left Align">

<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>

</button>

Here I create the click event for update button on which I am calling the updateStatus method.


updateStatus(item:Task){

this._taskdata.editTask(item)

.subscribe(

(data:any)=>{

if(item.Status=="done")

{

item.Status='pending';

}

else

{

item.Status='done';

}

},

function(error){

console.log(error);

},

function(){

console.log ('Edited successfully');

}

);

}

Summary

Github link

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.

4 thoughts on “Crud in angular2 part2

Leave a comment