DEV Community

Cover image for To Do App using Angular Forms - part 1
Lorenzo Zarantonello for This is Angular

Posted on • Updated on • Originally published at vitainbeta.org

To Do App using Angular Forms - part 1

Before we dive into creating an angular form, we need to clarify that there are two approaches to handle forms in Angular.

  • Template-driven approach. Your first set up the form in the template in your HTML code. Angular will then infer the structure of the form from there. The template-driven approach is the easiest way to get started with forms in Angular.
  • Reactive approach. You start from the class with your typescript code. The reactive approach is programmatical, and it potentially offers more advanced customization capabilities. Take a glance at What is RxJS.

In this post, we will use the template-driven approach.
If you are not familiar with event binding you may want to look at this simple app that explains it.

Template-driven Angular Form

Creating the form

We start by using the traditional <form> HTML element.

// app.component.html

<form>
  <label for="userInput">Add Task</label>
  <input
    placeholder="Write a task"
    name="userInput"
    required
  />
  <label for="date">By when</label>
  <input type="date" name="date" />
  <button type="submit">Add</button>
</form>
Enter fullscreen mode Exit fullscreen mode

As you can see, there is no action or method attribute. Unlike traditional HTML forms, we don't want to submit a form to some server. Angular should handle it.

At the moment, the application looks like this:

Image description

As usual, I will omit CSS but I will link the entire code later.

Make sure that you are importing FormsModule in app.module.ts! FormsModule is required to handle the form. Your app.module.ts should be similar to this:

//  app.module.ts

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

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

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }
Enter fullscreen mode Exit fullscreen mode

Thanks to FormsModule, Angular will automatically create a JavaScript representation of the form as soon as a form tag is detected in the template.

You can think of the JavaScript representation of the form as a regular JavaScript object that contains key-value pairs corresponding to the elements in the form.

Adding controls

Now, we need to tell Angular what kind of controls we have in the form. Angular doesn't detect the control elements automatically because not all elements need to be controls.

To tell Angular which element is a control we need to specify two things

  1. ngModel. We add ngModel to the element we want to use as a control. As you might know, ngModel is commonly used in two-way data binding.
  2. Name of the control. We need to specify the name of the control. So, we use the traditional HTML attribute name.
// app.component.html

<form>
  <label for="userInput">Add Task</label>
  <input 
    placeholder="Write a task" 
    ngModel 
    name="userInput" 
    required 
  />
  <label for="date">By when</label>
  <input  
    type="date"  
    name="date" 
    ngModel 
  />
  <button type="submit">Add</button>
</form>
Enter fullscreen mode Exit fullscreen mode

With this, I registered two elements in the JavaScript representation of the form.

I used the HTML attribute name to assign the name of the control, therefore this is also completed.

Submit Angular Forms

Angular Forms capitalizes on the default behavior of an HTML form. When a user clicks on the submit button, the button submits the form, triggers a request and submit a javascript submit event.

Angular uses the ngSubmit directive in the form tag. ngSubmit is an event listener that will fire whenever the form is submitted.
To verify that this is working fine, we add the event listener to the form tag.

// app.component.html

<form (ngSubmit)="onSubmit()">
  ...
</form>
Enter fullscreen mode Exit fullscreen mode

The ngSubmit event listener triggers the onSubmit() method that we have to create in our component. For the moment, the onSubmit() method logs a string into the console.

app.component.ts

export class AppComponent {
  ...

  onSubmit() {
    console.log('Submitted');
  }
}

Enter fullscreen mode Exit fullscreen mode

When we click on the add button, we see the text Submitted in the console. Ok, that is already something! Angular submits the forms correctly or at least ngSubmit fires the event adeguately.

Pass Angular Forms data

We need to add some code to expose the data in the Angular Form. In other words, we want to get access to the automatically generated javascript object in the Angular form.

To get access to the object, we set a local reference equal to ngForm in the form tag #myForm="ngForm". This tells Angular to give us access to the form, read javascript object, created automatically.

// app.component.html

<form (ngSubmit)="onSubmit(myForm)" #myForm="ngForm">
  ...
</form>
Enter fullscreen mode Exit fullscreen mode

Notice that I passed the local reference myForm to the onSubmit method.

We need to update the onSubmit method in app.component.ts to receive the form object of type NgForm.

app.component.ts

import { NgForm } from '@angular/forms';
...

export class AppComponent {
  ...

  onSubmit(form: NgForm) {
    console.log('Submitted', form);
  }
}

Enter fullscreen mode Exit fullscreen mode

At this point, when you submit the form you can see the NgForm object in the console. Feel free to play around and peek inside the object. Curiosity is the best way to learn.

In the picture below, you can see a screenshot of part of the form object.
You can already see the controls and value keys
Image description

Inside the value property you will find the values associated with the controls that we defined above: userInput and date.

If you log form.form.value you will get an object:

{
    "userInput": "some user input abc",
    "date": "2022-02-09"
}
Enter fullscreen mode Exit fullscreen mode

Notice that you might want to use HTML5 validation. Since Angular disables it by default, it is necessary to add ngNativeValidate to the form in the template.

Latest comments (0)