Simple ToDo App In Angular - part 2

Simple ToDo App In Angular - part 2

Learn Angular by creating a simple app

In the previous post, we started building a simple to-do app and we were able to log data from the input element to the console.

If you click on the Add button you should see the value of userInput in the console.

Image description

In this post, we will do the following:

  • create an array to store a list of elements
  • save & display data from the input element
  • add functionality to remove items from the list

Create An Array To Store A List Of Elements

We need to add some code to our application to display a list of items.

Let's start from the template file, app.component.html.

Immediately under the form, we add the following code:

// app.component.html

...

<ul>
  <li *ngFor="let item of todoList">{{ item }}</li>
</ul>

I am assuming you are familiar with <ul> and <li> tags.

What is more interesting is that ngFor stuff. If you are not familiar with it, read the *ngFor syntax like this: For each item inside todoList, create a new <li> and add that item to the newly created <li>.

Where is todoList? We don't have it yet. But as the name suggests, todoList will contain a list of items. Later, we will add the data coming from the input element to todoList. Let's define an array that we call todoList into AppComponent.

// app.component.ts

...
export class AppComponent {
  title: string = 'Ng To Do';
  subtitle: string = 'Write something to do in the form';
  userInput: string | undefined;
  todoList: string[] = ['Study Angular', 'Add one elememt', 'Correct typo'];

  onSubmit(): void {
    console.log(this.userInput);
  }
}

Note that the type of todoList is string[] is typescript, and you can read it as an array of strings.

Save & Display Data From The Input Element

We will work with the onSubmit() method to add the user input to todoList.

// app.component.ts

...
onSubmit(): void {
    console.log(this.userInput);
    this.todoList = this.todoList.concat(this.userInput);
  }

You could use push() instead of the concat() method but I prefer to follow a functional programming pattern. For the purpose of this exercise, either one is fine.

Now, you can see the items coming from the input element in your app!

Image description

Remove Items From The List

We will remove items brutally. First of all, we add an onDelete() method to app.component.ts. onDelete() takes one parameter of type string. Then, we use the javascript filter() method and the functional programming pattern to create a copy of todoList that contains only the items left after the user decides to delete some items.

// app.component.ts

...
  onDelete(itemToDelete: string): void {
    this.todoList = this.todoList.filter((item) => item !== itemToDelete);
  }

Finally, to make magic happen we need to add some code to the template. As we did before, we will use event binding (click)="onDelete(item)".

// app.component.html

...

<ul>
  <li *ngFor="let item of todoList" (click)="onDelete(item)" 
   {{ item }}
  </li>
</ul>

This is kinda working. Now you can remove items by clicking on them. In other words, by clicking on the text you trigger the onDelete() method that executes the javascript code to filter out the item you want to delete.

You can find the code here.

Conclusion & New Beginning

The app is working, but it is definitely a raw piece of code. Accessibility is bad, items with the same text get deleted together, style... well, you see that.

However, since there are many ways to proceed, I need some push :smile:

So, here are some options, what do you prefer?

  1. Add some CSS to this crappy style
  2. Improve accessibility
  3. Improve functionality: one click, one delete
  4. Add validations to the input
  5. Rewrite this app to use proper Angular Forms

I'd love to hear your preferences in the comments or DM on Twitter.

Here is a simple Angular tutorial I am trying to put together.