Simple Angular To Do App - part 1
Tags: angular, webdev, typescript, tutorial
Published: 2022-02-06 10:06:56

Another to-do app??
Yes, and there is a reason for that.

There are some type of applications that force you to use some patterns that will be extremely common in your professional life. 

Think of a to-do app. 

- Create some way to input data
- Handle data (transform, save, etc)
- Display data elsewhere in your app. 
 
What do you do on Twitter? 
Sure, this is a simplification, but once you understand those patterns, they will serve you well.

Let's jump into the app.

## What are we going to use?

- Event binding
- Two-way binding
- Basic typescript

I will omit style in the post, but I will link the code later.
The app will look like this:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71qtzd5vtht0xgrui6ty.png)

## Creating the UI
Let's start by creating the user interface, just because it might be easier to understand on what I am working on.

```
// app.component.html

<h1>Ng To Do</h1>
<p>Write something to do in the form</p>

<input placeholder="Write and Add" />
<button>Add</button>
```

Everything is aligned to the top and the left because this is the default behavior. CSS will take care of that.

It is not a good practice to hardcode something, so we immediately move to app.component.ts to define two variables.


```
// app.component.ts

...
export class AppComponent {
  title: string = 'Ng To Do';
  subtitle: string = 'Write something to do in the form';
}
```

We defined a variable called title of type `string`. Then, we initialized it to _Ng To Do_. `string` is a [basic type in typescript](https://www.typescriptlang.org/docs/handbook/basic-types.html). It tells the compiler that the variable title can only be of type string. COngrats! You are using typescript :)

We follow the same logic for the variable subtitle.
Finally, we have to change the hardcoded text in the template to use the variables we just created.

```
// app.component.html

<h1>{{ title }}</h1>
<p>{{ subtitle }}</p>
...
```

## Pass data from input element

There are several ways to pass data in Angular
- [Property binding](https://www.vitainbeta.org/how-to-pass-data-property-to-child-components-in-angular/)
- [Angular Services](https://dev.to/this-is-angular/passing-data-with-angular-services-4mh)
- FormsModule and [FormGroup](https://angular.io/api/forms/FormGroup)

However, since we are working on a simple application, we will use a simple trick to get the same outcome.

### Two-way data binding
If you are not familiar with [two-way data binding](https://www.vitainbeta.org/passing-angular-data-to-the-parent-component/#two-way-binding), it is time to look at it.

The Angular documentation says “Two-way binding gives components in your application a way to share data. Use two-way binding to listen for events and update values simultaneously between parent and child components“.

First of all, we create a variable in app.component.ts and we call it userInput. It will store the data coming from the user through the input element. Since we are using typescript, we also assign a type to that variable `userInput: string;`.

Side Note: _Initially, userInput is undefined. TypeScript might complain because we just said that userInput should be a string. Indeed, we should say that userInput could be a string OR undefined by using a pipe `|` like this 'userInput: string | undefined;'. Read more on [composing types](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html#composing-types). _

Then, we work on the input element in the template (app.component.html) so that it updates the variable every time the user types something.

By adding `[(ngModel)]="userInput"` to the input element the variable userInput will store the value from the input element, and it will update whenever the user types something.

```
// app.component.html

... 
<input placeholder="Write and Add" [(ngModel)]="userInput" />
<button>Add</button>
```

Be aware that you need to import FormsModule from @angular/forms to use ngModel.

```
// app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }
``` 

At this point, we have a variable, userInput, that stores the data from the input element. However, we don't really know if this works! Let's check it right away.

## Logging Data
To check the value of userInput we will use event binding to [bind a click event](https://www.vitainbeta.org/passing-angular-data-to-the-parent-component/#event-binding). 

In other words, we will use the Add button to trigger a console.log() that logs the value of userInput.

### Adding Event Binding

The syntax to add event binding is similar to the syntax of two-way binding but more simple. 

We add `(click)="onSubmit()"` to the Add button tag. The first part listens to _click events_ and the second part, after the `=` symbol, triggers a method that we will define in app.component.ts.

```
// app.component.html

... 
<input placeholder="Write and Add" [(ngModel)]="userInput" />
<button (click)="onSubmit()">Add</button>
```

In app.component.ts we define an onSubmit() method that logs userInput, just to try out. 

```
// app.component.ts

...
export class AppComponent {
  title: string = 'Ng To Do';
  subtitle: string = 'Write something to do in the form';
  userInput: string;

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

Since we are using typescript, we tell the compiler that we do not expect any return from onSubmit by adding the type `void` to the definition of the method.

At this point, if you click on the Add button you should see the value of userInput in the console. Wohooooo!!! 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i9c1pi4ebdhcoxmviznk.png)

Well done, we are more than half-way through!
Keep working on [Simple Angular To Do App in part 2](https://www.vitainbeta.org/simple-angular-to-do-app-part-2/)! (link to original article)