CRUD operations in Ionic2 , To-Do application

Hello Readers,

Now It is time for Ionic2(Cross Platform Mobile App Using AngularJS and Typescript). If you know angularJS and Typescript then it is your “cup of tea”.

In this tutorial I am going to cover following topics.

  • HTTP Services(Providers)
  • Fetching JSON Data From URL
  • Add task
  • Conditionally applying css class
  • Delete Task
  • Update Task & more..

You can also find the code here, So feel free to play with code yourself. In this tutorial I am using Ionic2 CLI (Command Line Interface to have work convenience with ionic2). In other word by using cli it will create boiler plate ready for us. For setup and all other instructions please go through the previous article here..

In this tutorial I am going to make to-do application to simply list all task, add task, delete task and update task. I had already created the REST Api Using NodeJS.,so it will fetch data from mysql. My Task Table Contains 3 columns Id, Title & Status.

Creating Data Structure/Class:


export class Task {

constructor(public Id:String,public Title:String,public Status:String){}

}

 

First I had created class and named it as Task, it will be used to store the json data.

What are services?

We can say, services mean don’t repeat yourself (Dry)!

Now, what does it mean?

Let’s say for example, we require one function which can be used by more than one components. Then, what happens,  we just need to write the same code again and again for each component. When we want to change some logic in function, then we need to change it on each and every component.

i.e.  instead of doing this, we simply create a service in which we can write the code once that can be used by as many components as we want ,by simply injecting the service Instance. In other languages, services keeps our function and logic centralized.

In general, our service can perform the following tasks:

  • Communicate with database.
  • Communicate with components /classes.
  • Some other business logic which is accessible from various places of our application.

Creating Provider/Service:

cmd> ionic g provider dbtaskservice


public url:string="https://localhost:3000/Tasks/";

getAllTasks(){

return this._http.get(this.url)

.map((response:Response)=>response.json());

}

The above function will return all the task from the database. But before creating this function ,create the object of HTTP as shown below and also import rxjs/Rx for map and observable.


import { Injectable } from '@angular/core';

import { Task } from '../pages/tasks/task';

import { Http,Response,RequestOptions,Headers } from '@angular/http';

import { Observable } from "rxjs/Observable";

import  'rxjs/Rx';

@Injectable()

export class Dbtaskservice {

private allTask:Task[]=[];

private url:string="https://localhost:3000/Tasks/";

constructor(public _http: Http)

{

console.log('Hello Dbtaskservice Provider');

}

getAllTask()

{

return this._http.get(this.url)

.map((response:Response)=>response.json());

}

deleteTask(item:Task){

let headers = new Headers({ 'Content-Type': 'application/json' });

let options = new RequestOptions({ headers: headers });

return this._http.delete(this.url+item.Id,

options)

.map((response:Response)=>response.json());

}

addTask(item:Task){

let body = JSON.stringify(item);

let headers = new Headers({ 'Content-Type': 'application/json' });

let options = new RequestOptions({ headers: headers });

return this._http.post(this.url,

body, options)

.map((response:Response)=>response.json());

}

getTaskId(id:any){

return this._http.get(this.url+id)

.map((response:Response)=>response.json());

}

editTask(item:Task){

let body = JSON.stringify(item);

let headers = new Headers({ 'Content-Type': 'application/json' });

let options = new RequestOptions({ headers: headers });

return this._http.put(this.url+item.Id,

body, options)

.map((response:Response)=>response.json());

}

}

So here in above service I had created all methods for task like getAllTask(),addTask(),deleteTask() and more.

Important Point:

To make this service available to each component, it must be declared inside the provider array of app.module.ts (i.e. global declaration file) as shown below.


import { NgModule } from '@angular/core';

import { IonicApp, IonicModule } from 'ionic-angular';

import { MyApp } from './app.component';

import { AboutPage } from '../pages/about/about';

import { ContactPage } from '../pages/contact/contact';

import { Dbtaskservice } from '../providers/dbtaskservice';

@NgModule({

declarations: [

MyApp,

AboutPage,

ContactPage

],

providers: [Dbtaskservice]

})

Creating Component:

So far I had created class and service, now it’s turn for component to display all the task.

cmd>ionic g page tasks

it will generate tasks directory inside pages directory.

Ionic2 comes with global declaration concept. So, whenever creating a component, it must need to declare it in app.module.ts, inside the declaration array and entryComponents array  as shown below, then only it can be used.


import { NgModule } from '@angular/core';

import { IonicApp, IonicModule } from 'ionic-angular';

import { MyApp } from './app.component';

import { AboutPage } from '../pages/about/about';

import { ContactPage } from '../pages/contact/contact';

import { TasksPage } from '../pages/tasks/tasks';

@NgModule({

declarations: [

MyApp,

AboutPage,

ContactPage,

TasksPage

],

entryComponents: [

MyApp,

AboutPage,

ContactPage,

HomePage,

TasksPage

],

})

Component can be divide in to two part

  1. Html
  2. TypeScript

I will first start with TypeScript part. Now TypeScript can be further divide in 3 parts.

  1. Import section
  2. Component metadata
  3. Class

So, in our example –

  • First, create the array named it as allTasks which is the type of task(which is created earlier).
  • Then, inject the dbtaskservice inside the constructor and create the instance of our service.
  • And then finally, call getAllTask method of our service inside the ionViewDidLoad event.

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

import { NavController ,LoadingController ,ToastController } from 'ionic-angular';

import { Dbtaskservice } from '../../providers/dbtaskservice';

import { Task } from '. /task';

@Component({

selector: 'page-tasks',

templateUrl: 'tasks.html'

})

export class Tasks {

allTask:Task[]=[];

title:string;

id:string;

constructor(public navCtrl: NavController,public loadincontroller:LoadingController,public _dbtaskservice:Dbtaskservice,public _toast:ToastController){

}

ionViewDidLoad() {

let loadingdata=this.loadincontroller.create({

content:"Loading Tasks..."

});

loadingdata.present();

this._dbtaskservice.getAllTask().subscribe(

(data:Task[])=>{

this.allTask=data;

},

function (error){

console.log("error"+error)

},

function(){

loadingdata.dismiss();

}

);

}

}

In Above code, I had imported loadingcontroller from ionic-angular package, to show progress bar on loading also imported toastcontroller to display the message on successfully insert or delete or update the task. Now on html I will loop through the allTask array and display all the task. So the html will look like following.


<ion-header>

<ion-navbar>

<ion-title>taskdb</ion-title>

</ion-navbar>

</ion-header>

<ion-content padding>

<ion-list inset>

<ion-input placeholder="id" autofocus="" [(ngModel)]="id" ></ion-input>

<ion-input placeholder="What needs to be done?"  [(ngModel)]="title" (keyup.enter)="addTask()" ></ion-input>

<ion-item *ngFor="let t of allTask" ><!--(click)="taskSelected(t)"-->

<ion-label [ngClass]="{'donestatus': t.Status=='done','pendingstatus':t.Status=='pending'}" >{{t.Title}}</ion-label>

<ion-icon item-right (click)="deleteTask(t)"  ios="ios-trash" md="md-trash"></ion-icon>

<ion-icon item-right (click)="updateTask(t)"  ios="ios-color-wand" md="md-color-wand"></ion-icon>

<!--<ion-icon name="trash" ios="ios-trash" md="md-trash"></ion-icon>-->

</ion-item>

</ion-list>

</ion-content>

Here in above html I am also applying the class conditionally i.e. the completed task should be displayed in blue and uncompleted task should be displayed in red.


page-tasks {

.donestatus{

color: blue;

}

.pendingstatus{

color: red;

}

}

 

Also I had used two way binding for adding the task.


<ion-input placeholder="id" autofocus="" [(ngModel)]="id" ></ion-input>

<ion-input placeholder="What needs to be done?"  [(ngModel)]="title" (keyup.enter)="addTask()" ></ion-input>

Two way binding can be achieved using ngModel. Here I created the keyup event which fired on enter key pressed. Overall typescript will look like this after adding addTask,updateTask and deleteTask.


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

import { NavController ,LoadingController ,ToastController } from 'ionic-angular';

import { Dbtaskservice } from '../../providers/dbtaskservice';

import { Task } from './task';

@Component({

selector: 'page-tasks',

templateUrl: 'tasks.html'

})

export class Tasks {

allTask:Task[]=[];

title:string;

id:string;

constructor(public navCtrl: NavController,public loadincontroller:LoadingController,public _dbtaskservice:Dbtaskservice

,public _toast:ToastController){

&nbsp;

}

&nbsp;

ionViewDidLoad() {

console.log('Hello Taskdb Page');

let loadingdata=this.loadincontroller.create({

content:"Loading Tasks..."

});

loadingdata.present();

this._dbtaskservice.getAllTask().subscribe(

(data:Task[])=>{

this.allTask=data;

console.log(data);

},

function (error){

console.log("error"+error)

},

function(){

console.log("subscription done")

loadingdata.dismiss();

}

);

}

addTask(){

let loadingdata=this.loadincontroller.create({

content:"Posting Tasks..."

});

loadingdata.present();

this._dbtaskservice.addTask(new Task(this.id,this.title,'pending'))

.subscribe(

(data:Task)=>{

if(data!=null){

this.allTask.push(new Task(this.id,this.title,'pending'));

this.title='';

this.id='';

}

},

function(error){},

function(){

loadingdata.dismiss();

}

&nbsp;

);

}

updateTask(t:Task){

if(t.Status=='done')

{

t.Status='pending';

}

else

{

t.Status='done'

}

this._dbtaskservice.editTask(t).subscribe(

(data:any)=>{

&nbsp;

if(data.affectedRows==1)

{

let mes=this._toast.create({

message:'Task Updated Successfully',

duration:2000,

position:'bottom'

});

&nbsp;

mes.present();

}

else

{

let mes=this._toast.create({

message:'Error in Updating',

duration:2000,

position:'bottom'

});

&nbsp;

mes.present();

}

}

);

}

deleteTask(t:Task){

&nbsp;

this._dbtaskservice.deleteTask(t).subscribe(

(data:any)=>{

&nbsp;

if(data.affectedRows==1){

&nbsp;

let mes=this._toast.create({

message:'Task Deleted Successfully',

duration:2000,

position:'bottom'

});

this.allTask.splice(this.allTask.indexOf(t),1);

mes.present();

}

else{

let mes=this._toast.create({

message:'Error in deleting task',

duration:2000,

position:'bottom'

});

mes.present();

}

}

);

}

}

I had created the tab application so before running the application I must need to change the default page i.e. go to tab page and change the home page to tasks page as shown below


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

import { HomePage } from '../home/home';

import { AboutPage } from '../about/about';

import { ContactPage } from '../contact/contact';

import { Tasks } from '../tasks/tasks';

@Component({

templateUrl: 'tabs.html'

})

export class TabsPage {

// this tells the tabs component which Pages

// should be each tab's root Page

tab1Root: any = Tasks;

tab2Root: any = AboutPage;

tab3Root: any = ContactPage;

constructor() {

&nbsp;

}

}

So now all done and good to go to run to-do application.

Run application in browser

cmd>ionic serve

Run application in device

cmd>ionic run android

but before run on device I must need to add platform for it

cmd>ionic platform add android

Summary

Ionic2 is simply awesome. Isn’t it?

Download link

We covered a lot in this tutorial. Let’s just summarize it.

  • Ionic-CLI
  • Created class
  • Services
  • Components
  • Run time css class
  • Add,Update and Delete and more…

There is a lot more to come in the next part of the tutorial. So, stay tuned for more.

Advertisements

1 thought on “CRUD operations in Ionic2 , To-Do application”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s