How To Use Reactive Forms in Angular | DigitalOcean (2024)

Introduction

Angular provides two ways to work with forms: template-driven forms and reactive forms (also known as model-driven forms). Template-driven forms are the default way to work with forms in Angular. With template-driven forms, template directives are used to build an internal representation of the form. With reactive forms, you build your own representation of a form in the component class.

Note: Reactive forms were introduced with Angular 2.

Here are some of the advantages of reactive forms:

  • Using custom validators
  • Changing validation dynamically
  • Dynamically adding form fields

In this article, you will explore how reactive forms can be applied to an example Angular application.

Prerequisites

If you would like to follow along with this article, you will need:

  • Node.js installed locally, which you can do by following How to Install Node.js and Create a Local Development Environment.

This post assumes you have some basic knowledge of Angular.

This post also assumes you are building from a fresh Angular project generated by @angular/cli. You can refer to this post if you’re getting started with Angular CLI.

This tutorial was verified with Node v15.1.0, npm v6.14.8, @angular/core v11.0.0, and @angular/forms v11.0.0.

Step 1 — Setting Up the Project

For the purpose of this tutorial, you will build from a default Angular project generated with @angular/cli.

  1. npx @angular/cli new angular-reactive-forms-example --style=css --routing=false --skip-tests

This will configure a new Angular project with styles set to “CSS” (as opposed to “Sass”, Less", or “Stylus”), no routing, and skipping tests.

Navigate to the newly created project directory:

  1. cd angular-reactive-forms-example

To work with reactive forms, you will be using the ReactiveFormsModule instead of the FormsModule.

Open app.module.ts in your code editor amd add ReactiveFormsModule:

src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { ReactiveFormsModule } from '@angular/forms';import { AppComponent } from './app.component';@NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, ReactiveFormsModule, ], providers: [], bootstrap: [AppComponent]})export class AppModule { }

At this point, you should have a new Angular project with ReactiveFormsModule.

Step 2 — Adding a Form to the Component Template

With reactive forms, the logic is declared entirely in the component class.

Open app.component.html in your code editor and add the following lines of code:

src/app/app.component.html

<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)"> <div> <label> Name: <input formControlName="name" placeholder="Your name"> </label> </div> <div> <label> Email: <input formControlName="email" placeholder="Your email"> </label> </div> <div> <label> Message: <input formControlName="message" placeholder="Your message"> </label> </div> <button type="submit">Send</button></form>

This code will create a form with three fields: name, email, and message. There will also be a "submit" button with the label "Send". When submitting the form, the method onSubmit(myForm) will be called.

Note: If you are using Angular 2.x, you should also add the novalidate directive with the opening form tag, as Angular overrides HTML5’s validation. With Angular 4+, novalidate is automatically added behind the scenes.

Let’s break it down:

  • formGroup: The form will be treated as a FormGroup in the component class, so the formGroup directive allows to give a name to the form group.
  • ngSubmit: This is the event that will be triggered upon submission of the form.
  • formControlName: Each form field should have a formControlName directive with a value that will be the name used in the component class.

At this point, you should have a new Angular project with a component template that uses a form.

Step 3 — Building the Component Class

Next, in the component class, you will define the FormGroup and individual FormControls within the FormGroup.

If a value is provided when newing a FormControl, it will be used as the initial value for the field.

Notice how the FormGroup and FormControl names are the same that were used in the template. Also notice how you initialize the FormGroup in the ngOnInit lifecycle hook:

src/app/app.component.ts

import { Component, OnInit } from '@angular/core';import { FormControl, FormGroup } from '@angular/forms';@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css']})export class AppComponent implements OnInit { myForm: FormGroup; ngOnInit() { this.myForm = new FormGroup({ name: new FormControl('Sammy'), email: new FormControl(''), message: new FormControl('') }); } onSubmit(form: FormGroup) { console.log('Valid?', form.valid); // true or false console.log('Name', form.value.name); console.log('Email', form.value.email); console.log('Message', form.value.message); }}

For the purposes of this tutorial, the onSubmit method does not actually communicate the submitted form values to any external service or server. It serves to show how you can access the form’s validity and FormControl values.

At this point, you can compile your application and open it in a web browser. After entering values for name, email, and message and pressing Submit, the console log will display the values.

Step 4 — Updating the Component Class to Use FormBuilder

The ngOnInit form construction can be rewritten with the FormBuilder helper. This allows you to forgo of all the newing of form group and form controls.

Revisit app.component.ts in your code editor and remove FormControl and replace FormGroup with FormBuilder:

src/app/app.component.ts

import { Component, OnInit } from '@angular/core';import { FormBuilder, FormGroup } from '@angular/forms';@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css']})export class AppComponent implements OnInit { myForm: FormGroup; constructor(private fb: FormBuilder) {} ngOnInit() { this.myForm = this.fb.group({ name: 'Sammy', email: '', message: '' }); } onSubmit(form: FormGroup) { console.log('Valid?', form.valid); // true or false console.log('Name', form.value.name); console.log('Email', form.value.email); console.log('Message', form.value.message); }}

This code with FormBuilder reduces the amount of boilerplate code for creating a FormGroup.

Step 5 — Updating the Component Class to Use Validators

Add the Validators class to your imports and declare your form controls with arrays instead of simple string values.

The first value in the array is the initial form value and the second value is for the validator(s) to use. Notice how multiple validators can be used on the same form control by wrapping them into an array.

RevisitRevisit app.component.ts in your code editor and add Validators:

src/app/app.component.ts

import { Component, OnInit } from '@angular/core';import { FormBuilder, FormGroup, Validators } from '@angular/forms';@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css']})export class AppComponent implements OnInit { myForm: FormGroup; constructor(private fb: FormBuilder) {} ngOnInit() { this.myForm = this.fb.group({ name: ['Sammy', Validators.required], email: ['', [Validators.required, Validators.email]], message: ['', [Validators.required, Validators.minLength(15)]], }); } onSubmit(form: FormGroup) { console.log('Valid?', form.valid); // true or false console.log('Name', form.value.name); console.log('Email', form.value.email); console.log('Message', form.value.message); }}

This code adds required to the name, email, and message fields. It also ensures the email value uses the format of a valid email address. It also ensures that the message value is at least 15 characters long.

If any of these form requirements are not passing, the valid value will be false. If all of these form requirements are passing, the valid value will be true.

Step 6 — Accessing Form Value and Validity in the Template

In the template, you can access each FormControl’s value and validity and the value and validity of the whole form group as a whole.

Revisit app.component.html and use *ngIf to display feedback messages to the user if the form values are not valid:

src/app/app.component.html

<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)"> <div> <label> Name: <input formControlName="name" placeholder="Your name"> </label> <div *ngIf="myForm.get('name').invalid && (myForm.get('name').dirty || myForm.get('name').touched)"> Please provide a name. </div> </div> <div> <label> Email: <input formControlName="email" placeholder="Your email"> </label> <div *ngIf="myForm.get('email').invalid && (myForm.get('email').dirty || myForm.get('email').touched)"> Please provide a valid email address. </div> </div> <div> <label> Message: <input formControlName="message" placeholder="Your message"> </label> <div *ngIf="myForm.get('message').invalid && (myForm.get('message').dirty || myForm.get('message').touched)"> Messages must be at least 15 characters long. </div> </div> <button type="submit" [disabled]="myForm.invalid">Send</button></form>

This code checks to see if the user has interacted with the field (dirty or touched). Then, if the value is not passing the validation requirements, it will display the error message. The Send button will also be disabled until all the issues with the form values are addressed.

There are multiple ways to retrieve form control values. This example uses myForm.get('name') which is equivalent to myForm.controls.name. It is possible to retrieve error information with .hasError('required') or .errors.required.

Conclusion

In this article, you explored how reactive forms can be applied to an example Angular application. You used FormControl, FormGroup, FormBuilder, and Validators to construct an example form with validation. For additional functionality, consult the official documentation.

If you’d like to learn more about Angular, check out our Angular topic page for exercises and programming projects.

How To Use Reactive Forms in Angular | DigitalOcean (2024)
Top Articles
Craigslist Dating Ads Are Back — They’re Just On Instagram Now
Atlas Steel Targets
Otc School Calendar
Watch After Ever Happy 123Movies
Wal-Mart 140 Supercenter Products
Old Bahama Bay Quad Folding Wagon
Pizza Hut Order Online Near Me
Spur H0 » Details Trix H0 Profi Club Modell 2009
Select Walgreens Stores: Lasko 16&quot; Stand Fan $7.50 &amp; More + Free Store Pickup on $10+
Trey Yingst Parents Nationality
9:00 A.m. Cdt
Uwa Schedule
Ta Travel Center Las Cruces Photos
Trinket Of Advanced Weaponry
Craigslist Albany Oregon Free Stuff
Car Complaints Toyota
Craigslist Org Hattiesburg Ms
Stellaris Wargoal
Autotrader Ford Ranger
Anon Rotten Tomatoes
Hours For Autozone Near Me
Female Same Size Vore Thread
Guide:How to make WvW Legendary Armor
Craiglist Morgantown
‘There’s no Planet B’: UNLV first Nevada university to launch climate change plan
Shawn N. Mullarkey Facebook
Craigslist Eugene Motorcycles
Logisticare Transportation Provider Login
Maurice hat ein echtes Aggressionsproblem
Ixl.prentiss
715 Henry Ave
Wgu Admissions Login
Alabama Adventure Coupons
Keanu Reeves cements his place in action genre with ‘John Wick: Chapter 4’
Age Of Attila's Rain Crossword
Craigslist In Visalia California
Natalya's Vengeance Set Dungeon
Horseheads Schooltool
Sound Of Freedom Showtimes Near Cinergy Midland
Boostmaster Lin Yupoo
Degreeworks Sbu
Ece 2300 Osu
Standard Schnauzer For Sale Craigslist
Bryant Air Conditioner Parts Diagram
2026 Rankings Update: Tyran Stokes cements No. 1 status, Brandon McCoy, NBA legacies lead loaded SoCal class
Builders Best Do It Center
David Knowles, journalist who helped make the Telegraph podcast Ukraine: The Latest a runaway success
Erfolgsfaktor Partnernetzwerk: 5 Gründe, die überzeugen | SoftwareOne Blog
Rubrankings Austin
Morse Road Bmv Hours
Gunsmoke Noonday Devil Cast
Neuer Extraction-Shooter auf Steam will Escape from Tarkov Konkurrenz machen, wird von echten Militär-Veteranen entwickelt
Latest Posts
Article information

Author: Kelle Weber

Last Updated:

Views: 6448

Rating: 4.2 / 5 (73 voted)

Reviews: 88% of readers found this page helpful

Author information

Name: Kelle Weber

Birthday: 2000-08-05

Address: 6796 Juan Square, Markfort, MN 58988

Phone: +8215934114615

Job: Hospitality Director

Hobby: tabletop games, Foreign language learning, Leather crafting, Horseback riding, Swimming, Knapping, Handball

Introduction: My name is Kelle Weber, I am a magnificent, enchanting, fair, joyous, light, determined, joyous person who loves writing and wants to share my knowledge and understanding with you.