What Tools Will We Use?

  • Event binding
  • Two-way binding
  • Basic TypeScript syntax

Styling is intentionally left out of this discussion, though the final code will be linked at the end.
Here is what the finished app will resemble:

Simple Angular To Do App - part 1 — figure 1

Building the UI

Constructing the interface first makes sense since it gives us a clear view of what we are building toward.

// 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>
Enter fullscreen mode Exit fullscreen mode

The default alignment pushes everything to the top-left corner; CSS will handle the layout adjustments later.

Hardcoding values is rarely a sound approach, so we move straight to app.component.ts to set up two properties.

// app.component.ts

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

We declare a property called title typed as string and assign it the value Ng To Do. The string type is a fundamental type in TypeScript, which instructs the compiler that title may hold only string values. Congratulations—you are now using TypeScript!

The same pattern applies to the subtitle property.
Next, we swap the static text in the template for the properties we defined.

// app.component.html

<h1>{{ title }}</h1>
<p>{{ subtitle }}</p>
...
Enter fullscreen mode Exit fullscreen mode

Getting Data from the Input

Angular offers multiple mechanisms to transfer data:

Given the simplicity of this project, we will opt for a straightforward approach to achieve the desired result.

Two-Way Data Binding

If two-way data binding is unfamiliar, now is a good time to explore it.

Per the Angular documentation: "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, we create a property called userInput in app.component.ts to capture whatever the user types into the input field. Since this is TypeScript, we also specify its type: userInput: string;.

Quick note: _Initially, userInput has no value. TypeScript may raise a warning because we declared it as a string, but it could be undefined at first. To handle this, we can use a union type with a pipe | like so: userInput: string | undefined;. Learn more about composing types._

Next, we modify the input element in the template (app.component.html) so it syncs with the property whenever the user types.

Adding [(ngModel)]="userInput" to the input element ensures the userInput property holds the input's value and refreshes with every keystroke.

// app.component.html

... 
<input placeholder="Write and Add" [(ngModel)]="userInput" />
<button>Add</button>
Enter fullscreen mode Exit fullscreen mode

Do not forget to import FormsModule from @angular/forms; otherwise, ngModel will not work.

// 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 { }
Enter fullscreen mode Exit fullscreen mode

We now have a property, userInput, which holds whatever is typed into the input. But how can we confirm it actually works? Let's test it.

Logging the Data

To inspect the value of userInput, we will use event binding to listen for a click.

In essence, we will wire the Add button to invoke a console.log() that prints the value of userInput.

Introducing Event Binding

The syntax for event binding resembles two-way binding, though it is simpler.

We attach (click)="onSubmit()" to the Add button tag. The segment inside the parentheses listens for click events, while the part after the = calls a method we will create in app.component.ts.

// app.component.html

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

We define an onSubmit() method in app.component.ts that logs userInput as a quick sanity check.

// 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);
  }
}
Enter fullscreen mode Exit fullscreen mode

Since we are working with TypeScript, we add the return type void to let the compiler know that onSubmit will not return anything.

Now, clicking the Add button should print userInput to the console. Excellent!

Simple Angular To Do App - part 1 — figure 2

Great progress—we are past the halfway mark!
Continue with Part 2 of the Simple Angular To Do App! (link to original article)