By Md. Sabuj Sarker | 3/21/2018 | General |Beginners

Angular 5 To-Do List App - Part 4

Angular 5 To-Do List App - Part 4

In the last article we implemented a task canceling feature. To do so, we had to re-implement our component class and we had to rewrite our template. We no longer could stick with an array. We had to define a Task interface and worked in all the places following it. The code of the previous article can be found in chunks in the previous article and the complete project can be found in the Github repository Learn Angular With Sabuj. Browse to the branch named todo-app-part-3 to get the full project code of the previous article. To get the full project of the current article browse the branch named todo-app-part-4.

In this article we will add more features to our to-do application.

Deleting a Task

While implementing the cancellation feature we needed to depend on the index provided by the *ngFor. In this case we will need that index again. But before working on the functional part, we need to work on the presentational which is the templating stuff.

We have to create another column in our to-do list table to show the delete button that will be responsible for deleting a task for us. Let's create a Bootstrap button with the btn-danger class as we want to make it red to visually warn before you click.

<button class="btn btn-danger btn-xs"> Delete </button>

We need a method in the component that will be responsible for deleting tasks from the task list. So, you get it, we need a click handler like below:

<button class="btn btn-danger btn-xs" (click)="deleteTask(idx)"> Delete </button>

So, the added content of the additional column in the table will look like below:

 

<td>
   <button class="btn btn-danger btn-xs" (click)="deleteTask(idx)"> Delete </button>
</td>

And our final template will look like this:

<div class="container">
   <div class="row">
       <div class="col-xs-12">
           <h1> To-Do Application </h1>
       </div>
   </div>
</div>

<div class="container">
   <div class="row">
       <div class="col-xs-8">
           <input type="text" class="form-control" name="task" placeholder="Task" #taskInput>
       </div>

       <div class="col-xs-4">
           <button class="btn btn-info" (click)="addTask(taskInput.value)">Add</button>
       </div>
   </div>

   <div class="row">
       <div class="col-xs-12">
           <table class="table table-striped">
               <thead>
                   <tr>
                       <th>To-Do list</th>
                   </tr>
               </thead>
               <tbody>
                   <tr *ngFor="let task of tasks; let idx = index">
                       <td *ngIf="task.is_canceled; else elseTd">
                           <s>{{ idx + 1 }}. {{task.title}}</s>
                       </td>
                       <ng-template #elseTd>
                           <td>{{ idx + 1 }}. {{task.title}}</td>
                       </ng-template>

                       <td>
                           <button class="btn btn-warning btn-xs" (click)="cancelTask(idx)"> Cancel </button>
                       </td>
                       <td>
                           <button class="btn btn-danger btn-xs" (click)="deleteTask(idx)"> Delete </button>
                       </td>
                   </tr>

               </tbody>
               <tfoot>
                   <tr>
                           <button class="btn btn-danger" (click)="clearToDo()">Clear</button>
                   </tr>
               </tfoot>
           </table>
       </div>
   </div>
</div>

The frontend of our application will look like below now:

We need to create the deleteTask() inside our component accordingly:

deleteTask(idx: number){
   this.tasks.splice(idx, 1);
 }

We told the splice method to start deleting elements at the index and stop when it has deleted one element. That is the equivalent of removing the element at the position of the index. Now it's time to go to the browser and start clicking the delete button, adding new elements and deleting them too. Check to see in all the ways to make sure that things are OK.

Confirming Deletion

In our application nothing asks for our confirmation before deleting tasks. It is a good practice to ask permission before doing anything dangerous so we don’t accidentally or unintentionally hit the delete button. We could use Bootstrap modal for that but we will not, because that depends on Bootstrap specific JavaScript and jQuery and we do not want to use jQuery like stuff inside Angular. When we have a great framework like Angular then it is a big NO to use things like jQuery. We need an Angular specific version of Bootstrap instead of the default Bootstrap. But that is left for later when I write more articles to teach you Angular fundamentals.

So, for now, we will use the default confirm() function. Let's do the following inside of our deleteTask() method.

 deleteTask(idx: number){
   let do_delete = confirm("Are you sure to delete the task?");
   if (do_delete){
     this.tasks.splice(idx, 1);
   }
 }

The confirm() function will return true when you click the Ok button and it will return false when you call the Cancel button of the prompt. So, our deleteTask() method only deletes the task when there is a true value in do_delete variable.

Clearing Confirmation

Clearing is like deleting each and every task from our list of tasks. That is a much more dangerous than deleting a single task. So, let's implement the confirmation logic inside our clearToDo().

 clearToDo(){
   let do_delete = confirm("Are you sure to delete all tasks?");
   if (do_delete){
     this.tasks.splice(0);
   }
 }

Go to the browser again to check if things are going according to our expectation.

The final state of our component will look like below:

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

interface Task{
 title: string,
 is_canceled: boolean
}

@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent {
 tasks: Array<Task> = [
   {
     title: "Go home",
     is_canceled: false
   },
   {
     title:"Take a nap",
     is_canceled: false
   },
   {
     title: "Start learning Angular with Sabuj",
     is_canceled: false
   }
 ];

 clearToDo(){
   let do_delete = confirm("Are you sure to delete all tasks?");
   if (do_delete){
     this.tasks.splice(0);
   }
 }

 addTask(value: string){
   this.tasks.push(
     {
       title: value,
       is_canceled: false
     });
 }

 cancelTask(idx: number){
   if (this.tasks[idx].is_canceled){
     this.tasks[idx].is_canceled = false;
   }else{
     this.tasks[idx].is_canceled = true;
   }
 }

 deleteTask(idx: number){
   let do_delete = confirm("Are you sure to delete the task?");
   if (do_delete){
     this.tasks.splice(idx, 1);
   }
 }
}

Conclusion

We are advancing in our journey of developing a full featured to-do application with the help of Angular 5. We are solving our problems chunk by chunk. Keep practicing Angular by working on this kind of  to-do application. Whenever you have a question create an issue on the Github repository Learn Angular with Sabuj.

 

Previous article: Angular 5 to do list app - Part 3

Next article: Angular 5 To-Do List App - Part 4

 

About the Author

My name is Md. Sabuj Sarker. I am a Software Engineer, Trainer and Writer. I have over 10 years of experience in software development, web design and development, training, writing and some other cool stuff including few years of experience in mobile application development. I am also an open source contributor. Visit my github repository with username SabujXi.

By Md. Sabuj Sarker | 3/21/2018 | General

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Recent Stories

Top DiscoverSDK Experts

User photo
3355
Ashton Torrence
Web and Windows developer
GUI | Web and 11 more
View Profile
User photo
3220
Mendy Bennett
Experienced with Ad network & Ad servers.
Mobile | Ad Networks and 1 more
View Profile
User photo
3060
Karen Fitzgerald
7 years in Cross-Platform development.
Mobile | Cross Platform Frameworks
View Profile
Show All
X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now