Angular is a popular front-end framework made by Google. Like other popular front-end frameworks, it uses a component-based architecture to structure apps.
In this article, we’ll look at the basics of creating reactive forms with Angular.
Reactive Forms
Reactive forms use an explicit and immutable approach to managing the state of a form at a given point in time. Each change returns a new state, which maintains the integrity of the model between changes.
It’s also easier to test because the data is consistent and predictable.
We can create a Reactive form as follows:
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 {}
app.component.ts
:
import { Component } from "@angular/core";
import { FormControl } from "@angular/forms";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
nameControl = new FormControl("");
}
app.component.html
:
<input type="text" [formControl]="nameControl" />
<p>{{ nameControl.value }}</p>
In the code above, we imported the ReactiveFormsModule
in app.module.ts
.
Then in AppComponent
, we added a FormControl
called nameControl
.
Then we connect our input element to nameControl
by using the formControl
property.
To display the value we typed in, we reference the nameControl
‘s value
property as we did with the p element.
Replacing a Form Control Value
We can call the setValue
method on a FormControl
to replace the value of it.
For example, we can write the following code:
app.component.ts
import { Component } from "@angular/core";
import { FormControl } from "@angular/forms";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
nameControl = new FormControl("");
updateName() {
this.nameControl.setValue("Jane");
}
}
app.component.html
:
<input type="text" [formControl]="nameControl" />
<button (click)="updateName()">Update Name</button>
In the code above, we have the updateName
method which calls setValue
to set the value of FormControl
.
When we click the button, we’ll see Jane entered in the input.
Grouping Form Controls
We can create a FormGroup
to group form controls together.
For example, we can use it as follows:
app.component.ts
:
import { Component } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
personForm = new FormGroup({
nameControl: new FormControl("")
});
}
app.component.html
:
<form [formGroup]="personForm">
<input type="text" formControlName="nameControl" />
</form>
We bound the form to personForm
by using the formGroup
property.
Then we set the form control in the form group by using the formControlName
property.
Submitting Form Data
We can submit data entered into a Reactive form by attaching an onSubmit
handler to our form.
To do that we can write the following:
app.component.ts
:
import { Component } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
personForm = new FormGroup({
nameControl: new FormControl("")
}); onSubmit() {
console.log(this.personForm.value);
}
}
app.component.html
:
<form [formGroup]="personForm" (ngSubmit)="onSubmit()">
<input type="text" formControlName="nameControl" />
<button type="submit">Submit</button>
</form>
In the code above, we have the onSubmit
handler, which gets the value of all the fields entered by accessing the value
property of the form group.
When we click Submit, we should see what we typed in.
To disable the Submit button if the form isn’t valid, we can write:
app.component.html:
<button type="submit" [disabled]="!personForm.valid">Submit</button>
to set the disabled
property of the button when the personForm
‘s valid
value.
Creating Nested Form Groups
We can nest form groups. For example, we can write the following code to do that:
app.component.ts
:
import { Component } from "@angular/core";
import { FormControl, FormGroup } from "@angular/forms";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
personForm = new FormGroup({
name: new FormControl(""),
address: new FormGroup({
street: new FormControl("")
})
}); onSubmit() {
console.log(this.personForm.value);
}
}
app.component.html
:
<form [formGroup]="personForm" (ngSubmit)="onSubmit()">
<input type="text" formControlName="name" placeholder="Name" />
<div formGroupName="address">
<input type="text" formControlName="street" placeholder="Street" />
</div>
<button type="submit">Submit</button>
</form>
In the code above, we have the personForm
form group with the name
FormControl
in the root.
Then we added the address
FormGroup
, which has the street
FormControl
inside.
In app.component.html
, we bind the form to the personForm
FormGroup
as usual, but we have an extra div to bind the div
and what’s inside to the address
FormGroup
.
Then we bind the street
FormControl
to our input inside.
Conclusion
We can create FormControl
s and bind input elements to them.
Also, we can create FormGroup
s and bind forms to them.
FormGroup
s can be nested within each other.
We can access a FormGroup
and FormControl
‘s values with the value
property.