Angular – Reactive Forms

By | 25/09/2019

From https://angular.io/guide/forms-overview:
Applications use forms to enable users to log in, to update a profile, to enter sensitive information, and to perform many other data-entry tasks.
Angular provides two different approaches to handling user input through forms: reactive and template-driven. Both capture user input events from the view, validate the user input, create a form model and data model to update, and provide a way to track changes.
Reactive and template-driven forms process and manage form data differently. Each offers different advantages.

In general:

  • Reactive forms are more robust: they’re more scalable, reusable, and testable. If forms are a key part of your application, or you’re already using reactive patterns for building your application, use reactive forms.
  • Template-driven forms are useful for adding a simple form to an app, such as an email list signup form. They’re easy to add to an app, but they don’t scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, use template-driven forms


In this post, we will see how to define a Form (using Reactive forms approach) for creating new users in the usual angular project: Angular – How to add a menu in a project.

First of all, we have to register the ReactiveFormModule into app.module.ts, in order to use it in the project.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http'; 
import { ReactiveFormsModule } from '@angular/forms';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ListusersComponent } from './listusers/listusers.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TopmenuComponent } from './topmenu/topmenu.component';
import { HomepageComponent } from './homepage/homepage.component';
import { NewuserComponent } from './newuser/newuser.component';

@NgModule({
  declarations: [
    AppComponent,
    ListusersComponent,
    TopmenuComponent,
    HomepageComponent,
    NewuserComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    BrowserAnimationsModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }



Now, in order to create the “NewUser” functionality, we have to add some functions and variables into Newuser component:

[NEWUSER.COMPONENT.TS]

export class NewuserComponent implements OnInit {
  // the FormGroup represents the Form 
  // used to create a new User 
  userForm: FormGroup;
  submitted = false;
  // for this example, I put in the code the list of
  // typeUser.
  // In a real application I must use a Web API to get 
  // the list!
  typeUser: Array<string> = [
    'Admin',
    'Reader',
    'Writer'
  ];
  constructor(private formBuilder: FormBuilder, private serviceuser: WebapiuserService, private router: Router) { 
    // In the constructor I define the controllers of the Form
    this.userForm = this.formBuilder.group({
      'username': ['', Validators.required],
      'typeUserName': ['', Validators.required]
    });
  }

  ngOnInit() {
  }

  onSubmit() {
    this.submitted = true;

    // stop here if form is invalid
    if (this.userForm.invalid) {
        return;
    }

    // call the method to create a new user
    this.serviceuser.createUser(this.userForm.value)
    .subscribe(
      // if it's ok, call the method newUserOk
      data => this.newUserOK(),
      error => console.log("Error", error)
    )
  }

  newUserOK()
  {
    // I show a message 
    alert("New user " + this.f.username.value + "was created!");
    // and go to the List Users page
    this.router.navigate(['/listusers']);
  }

  // easy access to form fields
  get f() { return this.userForm.controls; }



Then, we define the Form into the HTML page of Newuser component:

[NEWUSER.COMPONENT.HTML]

<div class="jumbotron">
    <div class="container">
        <div class="row">
            <div class="col-md-6 offset-md-3">
                <h3>New User with Reactive Form</h3>
                <form [formGroup]="userForm" (ngSubmit)="onSubmit()">
                    <div class="form-group">
                        <label>User Name</label>
                        <input type="text" formControlName="username" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.username.errors }" />
                        <div *ngIf="submitted && f.username.errors" class="invalid-feedback">
                            <div *ngIf="f.username.errors.required">User Name is required</div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label>Type User Name</label>
                        <select class="form-control" name="typeUserName" id="typeUserName" formControlName="typeUserName" [ngClass]="{ 'is-invalid': submitted && f.typeUserName.errors }">
                            <option *ngFor="let item of typeUser" [ngValue]="item">{{item}}</option>
                        </select>
                        <div *ngIf="submitted && f.typeUserName.errors" class="invalid-feedback">
                            <div *ngIf="f.typeUserName.errors.required">Type User Name</div>
                        </div>
                    </div>
                    <div class="form-group">
                        <button class="btn btn-primary">Register</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>



Finally, we have to add the method createUser into the “service”:

[WEBAPIUSER.SERVICE.TS]

createUser(inputUser: User){
    return this.http.post<User>(this.webapiUserUrl + '/user', inputUser);
  }  



In order to verify that the new Form works fine, we run (with the command ng serve) the application and we try to add a new user:







Leave a Reply

Your email address will not be published. Required fields are marked *