Creating a Task Manager App Using Ionic: Part 2

In the first part of the tutorial series, you created the user interface and navigation for the task manager app. In this tutorial, you’ll see how to implement the functionality for the Ionic task manager app to add and list tasks.

Getting Started

Let’s get started by cloning the source code from the first part of the tutorial series.

git clone https://github.com/royagasthyan/IonicTaskManager-Part1

Navigate to the project directory and install the required dependencies.

cd IonicTaskManager-Part1
npm install

Run your app from the project directory.

ionic serve

You should have the application running at http://localhost:8100/.

Communicating Between Components

You have already created the Add component and List component to add tasks and to list tasks respectively. In order to make them work in sync, you need to maintain communication between the two components. To communicate between the components, you’ll make use of an injectable CommonService.  

Create a folder called service in the src/pages folder.

Create a service file called common.service.ts and add the following code:

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

@Injectable()
export class CommonService {
 
	constructor(){
		this.tasks = []
	}
}

You’ll keep track of the tasks list in the common service, and it will be shared between the Add and List components.

Define a variable called tasks in the common.service.ts file. You’ll keep your task list in this tasks array.

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

@Injectable()
export class CommonService {
    
    public tasks:any;

	constructor(){
		this.tasks = []
	}

}

Create a folder called task inside the src/pages folder. Create a file called task.model.ts and add the following code:

export class Task{
    constructor(
		public Id: Number,
		public Name: String,
		public IsDone: Boolean
	) { }
}

You’ll use the above Task class to create an instance of a new task.

When the user clicks on the Add task button from the Add component, you’ll add items to the tasks variable in the common.service.ts file. So create a method called addTask in the common.service.ts file, which you’ll call from the Add component.

import { Injectable } from '@angular/core';
import { Task } from '../model/task.model'

@Injectable()
export class CommonService {
    public tasks:any;

	constructor(){
		this.tasks = []
	}

	addTask(item){
		this.tasks.push(new Task((new Date()).getTime(),item,false));
	}
}

Add a Task to the List

In order to add a task to the task list, you need to import the common.service.ts file inside the AddPage component.

import { CommonService } from '../service/common.service'

Initialize the CommonService inside the AddPage component constructor method.

  constructor(public viewCtrl: ViewController, private commonService: CommonService) {

  }

Inside the AddPage component, create a method called add where you’ll add the task to the common service tasks list.

Here is how the add method in the AddPage component looks:

add(){
  this.commonService.addTask(this.item);
  this.dismiss();
}

As seen in the above method, you have called the addTask method from the common service to add a task to the tasks list.

Once the item is added, you have called the dismiss method to dismiss the pop-up overlay. Here is how the add.component.ts file looks:

import { Component } from '@angular/core';
import { ViewController } from 'ionic-angular';
import { CommonService } from '../service/common.service'

@Component({
  selector: 'page-add',
  templateUrl: 'add.component.html'
})
export class AddPage {


  public tasks: any = [];
  public item:String;

  constructor(public viewCtrl: ViewController, private commonService: CommonService) {

  }

  dismiss(){
      this.viewCtrl.dismiss();
  }

  add(){
  	this.commonService.addTask(this.item);
  	this.dismiss();
  }

}

In the add.component.html page, add the ngModel directive to the input element.

 <ion-input name="add" [(ngModel)]="item"></ion-input>

Add the click event to the button in the add.component.html to trigger the add method inside the add.component.ts.

<button ion-button round (click)="add()">Add</button>

Save the above changes and try to restart the ionic server. Navigate the browser URL to http://localhost:8100, and you should be able to view the mobile app in the browser.

Click on the Add icon to add a task. Enter the task name and click the add button. The pop-up should disappear.

Listing Task List Items

Once the task gets added in the tasks list, you need to update the view accordingly. So, to track the task when added to the list, you’ll need to use Angular Subject.

Define a subject called task_subject inside the common.service.ts file.

public task_subject = new Subject<String>()

When the task gets added to the tasks list, you need to trigger the subject task_subject to inform the subscriber that a task has been added.

Modify the addTask method inside the common.service.ts file to include the following code:

this.task_subject.next();

Here is the modified addTask method:

addTask(item){
	this.tasks.push(new Task((new Date()).getTime(),item,false));
	this.task_subject.next();
}

Subscribe to the subject task_subject inside the list.component.ts file.

constructor(public modalCtrl: ModalController, public commonService:CommonService) {
   this.commonService.task_subject.subscribe(response => {
		this.tasks = this.commonService.tasks;
	})
}

Whenever a new task is added the tasks from the commonService is assigned to the tasks in list.component.html and the view is updated.

Here is how the list.component.ts code looks:

import { Component } from '@angular/core';
import { ModalController } from 'ionic-angular';
import { AddPage } from '../add/add.component';
import { CommonService } from '../service/common.service'

@Component({
  selector: 'page-list',
  templateUrl: 'list.component.html'
})
export class ListPage {

  public tasks=[];
  constructor(public modalCtrl: ModalController, public commonService:CommonService) {
  	 
  	 this.commonService.task_subject.subscribe(response => {
			this.tasks = this.commonService.tasks;
		})
  }

  presentAddModal() {
   let addModal = this.modalCtrl.create(AddPage);
   addModal.present();
  }

}

Modify the list.component.html to iterate over the tasks variable from the list.component.ts file. Here is how it looks: 

<ion-list>

  <ion-item *ngFor="let item of tasks">
    <ion-label>{{item.Name}} </ion-label>
    <ion-checkbox name="chk"></ion-checkbox>
  </ion-item>

</ion-list>

Save the above changes and restart the server. Try to add a new task and it will get displayed on the listing screen.

Ionic Task Manager

Now let’s implement the functionality to mark the finished tasks. Each time a new task is added, you are adding an IsDone attribute as false.

Let’s keep two different arrays for pending tasks and finished tasks.

public pendingTasks = []
public doneTasks = []

Each time a new task is added, you’ll update the above two arrays as shown:

constructor(public modalCtrl: ModalController, public commonService:CommonService) {
   
  this.commonService.task_subject.subscribe(response => {
	this.pendingTasks = this.commonService.tasks.filter(item => {
		return item.IsDone == false
	});
	this.doneTasks = this.commonService.tasks.filter(item => {
		return item.IsDone == true
	});
})
}

When the user clicks on the check box, you need to toggle the IsDone status. Add a method called checkPendingItem to toggle the IsDone status for pending tasks.

 checkPendingItem(id){
      
  	this.pendingTasks.map((task) => {
      if(task.Id == id){
        if(task.IsDone){
          task.IsDone = false;
        } 
        else{
          task.IsDone = true;
        }
      }
    })


   this.updateTask()
  	
  }

Similarly, add another method called checkDoneItem to toggle the task status for done items. Here is how the method looks:

checkDoneItem(id){
  
  this.doneTasks.map((task) => {
  if(task.Id == id){
    if(task.IsDone){
      task.IsDone = false;
    } 
    else{
      task.IsDone = true;
    }
  }
})


this.updateTask()
  
}

Once the IsDone status is toggled, you need to update the tasks. Define a method called updateTask, which is called after IsDone toggle in both of the above methods.

updateTask(){
  this.pendingTasks = this.commonService.tasks.filter(item => {
	return item.IsDone == false
  });
  this.doneTasks = this.commonService.tasks.filter(item => {
	return item.IsDone == true
  });
}

Modify the list.component.html code to display the pendingTasks and doneTasks separately. Here is how the modified list.component.html file looks:

<ion-header>
    <ion-navbar>
        <ion-title text-center>Ionic Task Manager</ion-title>
    </ion-navbar>

</ion-header>

<ion-content padding>
    <ion-fab top right>
        <button ion-fab mini (click)="presentAddModal()"><ion-icon name="add"></ion-icon></button>
    </ion-fab>

    <ion-card>
        <ion-card-header>
            My Tasks
        </ion-card-header>

        <ion-list>

            <ion-item *ngFor="let item of pendingTasks">

                <ion-label>{{item.Name}} </ion-label>
                <ion-checkbox name="chk" (click)="checkPendingItem(item.Id)" [checked]="item.IsDone"></ion-checkbox>
            </ion-item>

        </ion-list>
    </ion-card>

    <ion-card>
        <ion-card-header>
            Archived Tasks
        </ion-card-header>

        <ion-list>

            <ion-item *ngFor="let item of doneTasks">

                <ion-label color="light">{{item.Name}} </ion-label>
                <ion-checkbox name="chk" (click)="checkDoneItem(item.Id)" [checked]="item.IsDone"></ion-checkbox>

            </ion-item>

        </ion-list>
    </ion-card>

</ion-content>

Save the above changes and restart the ionic server. You should have the application running at http://localhost:8100.

Ionic Task Manager App Listing

Wrapping It Up 

In this tutorial, you saw how to implement the functionality to add and list the tasks in the Ionic task manager mobile app. You saw how to use an Angular service to share data between two components. In this tutorial, you used the Angular service to keep data in a common list when added from the Add component and display it in the List component.

Do let us know your thoughts in the comments below.

Source code from this tutorial is available on GitHub.

Leave a Reply

Your email address will not be published. Required fields are marked *