January 15, 2019

Building User Registration Form With Reactive Forms in Angular 7

by Jay Raj

Building User Registration Form With Reactive Forms in Angular 7

In this tutorial, you'll learn how to handle Angular web app forms using Reactive Forms. From the official documentation,

Reactive forms use an explicit and immutable approach to managing the state of a form at a given point in time. Each change to the form state returns a new state, which maintains the integrity of the model between changes.

Reactive forms use a model driven approach to handle form input values. Let's see how to use Reactive forms in Angular.

The source code from this tutorial is available on GitHub.

Creating a User Registration UI Using Reactive Forms

Let's start by creating an Angular app from scratch and see how you can use Reactive forms in Angular 7.

Assuming that you have already installed the Angular CLI in your system, let's create an Angular app using the Angular CLI command.

ng new form-app

The above command creates an Angular project with some boilerplate code. Let's have a look at the boilerplate code.

Inside your form-app/src/app folder, you'll find the default AppComponent. Let's remove the default component from the project. Remove all files from the app folder except the app.module.ts file.

Once you have removed the default component, let's create a root component for the Angular app.

ng generate component root

Update the app.module.ts file to remove the AppComponent and update the bootstrap property in NgModule to RootComponent.

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

import { RootComponent } from './root/root.component';

@NgModule({
  declarations: [
    RootComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [RootComponent]
})
export class AppModule { }

Save the above changes and try running the Angular app.

npm start

You'll be able to see the default app running.

Let's start creating the form UI. You'll be making use of the FormBuilder to create a Reactive form. Inside the RootComponent class, import the FormBuilder module.

import { FormBuilder } from '@angular/forms';

Instantiate the FormBuilder module inside the RootComponent constructor.

constructor(private formBuilder: FormBuilder) { }

Using the FormBuilder module, create a form group which will define the fields in the form.

ngOnInit() {
    this.userForm = this.formBuilder.group({
      firstName: [''],
      lastName: [''],
      email: [''],
      password: [''],
    });
  }

Once you have defined the form builder group, set up the RootComponent form with the form group userForm. Add formGroup directive to the form inside root.component.html file.

<form [formGroup]="userForm" class="text-center border border-light p-5">

    <p class="h4 mb-4">Sign up</p>

    <div class="form-row mb-4">
        <div class="col">
            <input type="text" id="defaultRegisterFormFirstName" class="form-control" placeholder="First name">
        </div>
        <div class="col">
            <input type="text" id="defaultRegisterFormLastName" class="form-control" placeholder="Last name">
        </div>
    </div>

    <input type="email" id="defaultRegisterFormEmail" class="form-control mb-4" placeholder="E-mail">
  
    <button class="btn btn-info my-4 btn-block" type="submit">Sign in</button>

    <hr>

</form>

Add the formControlName to each element in the form as in the userGroup.

<form [formGroup]="userForm" (ngSubmit)="onSubmit()" class="text-center border border-light p-5">

  <p class="h4 mb-4">Sign up</p>

  <div class="form-row mb-4">
      <div class="col">
          <input type="text" formControlName="firstName" id="defaultRegisterFormFirstName" class="form-control" placeholder="First name">
      </div>
      <div class="col">
          <input type="text" formControlName="lastName" id="defaultRegisterFormLastName" class="form-control" placeholder="Last name">
      </div>
  </div>

  <input type="email" formControlName="email" id="defaultRegisterFormEmail" class="form-control mb-4" placeholder="E-mail">

  <button class="btn btn-info my-4 btn-block" type="submit">Sign in</button>

  <hr>

</form>

Save the above changes and point your browser to http://localhost:4200/. You will be able to see the user form.

Validating The User Registration Form Fields In Reactive Forms

You can validate the form using the Validators module. Import the Validators module inside the RootComponent.

import { FormBuilder, Validators } from '@angular/forms';

While initializing the form group elements, you can set validation for each of the fields using the validators module. For setting up a required field validation, you can use Validators.required as shown:

    this.userForm = this.formBuilder.group({
      firstName: ['', [Validators.required]],
      lastName: ['',[Validators.required]],
      email: ['', [Validators.required]]
    });

Let's set a submit button method on the user form. Add (ngSubmit)="onSubmit()" on the root.component.html file. Add the onSubmit method inside the RootComponent class.

  onSubmit(){
    if(this.userForm.valid){
      alert('User form is valid!!')
    } else {
      alert('User form is not valid!!')
    }
  }

To check if the userForm field is validated, you can use userForm.valid as shown in the onSubmit method.

Save the above changes and click the form with empty fields. You will get an alert saying User form is not valid.

Similarly, you can add custom validation based on regular expression patterns to the form fields. Let's add a pattern to allow only strings in the first name and last name field and email in the email field.
Add the validators to the user form group in the root.component.ts file.

ngOnInit() {
    this.userForm = this.formBuilder.group({
      firstName: ['', [Validators.required, Validators.pattern('^[a-zA-Z]+$')]],
      lastName: ['',[Validators.required, Validators.pattern('^[a-zA-Z]+$')]],
      email: ['', [Validators.required, Validators.email]]
    });
  }

Save the above changes and try to submit the form with numeric values in the first name or last name. You will be able to see an alert message saying that the values are not valid.

Protect your Angular App with Jscrambler

Submitting The Reactive Form

For submitting the reactive form, you'll need a REST endpoint to POST the form. So, first, you'll be creating a simple Express REST API endpoint returning the posted form values.

Creating The REST Endpoint

Let's get started by creating a Node Express server with a REST endpoint. Create a project folder called node-app. Navigate to the project folder and initialize the Node project.

mkdir node-app
cd node-app
npm init

You now have a Node project created in the node-app folder. You'll be using the Express framework for creating the REST API. Start by installing Express using npm.

npm install --save express

The command above installs the express framework to your Node project and also saves the dependency in the package.json file.

Create a file called app.js which will act as the root file of the server. Require the Express module inside the app.js file and create an Express app.

const express = require('express')
const app = express()

Using Express, create a route which will act as a REST API endpoint.

app.post('/api/userCreate', (req, res) => {
    res.json({
        data: req.body
    })
})

The route defined above returns the request parameters posted to the REST API endpoint URL.
You need to bind the Express app to a port address to run the server. So, here is how the app.js file looks:

const express = require('express')
const app = express()
const port = 3000

app.post('/api/userCreate', (req, res) => {
    res.json({
        data: req.body
    })
})

app.listen(port, () => console.log(`Server listening on port ${port}!`))

For parsing the form request body parameters, you'll need to use a module called body-parser. Install the body-parser and include it inside your Express app.

npm install --save body-parser

After adding body-parser to your Express app, here is how the app.js file looks:

const express = require('express')
const bodyParser = require('body-parser')

const app = express()
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
const port = 3000

app.post('/api/userCreate', (req, res) => {
    res.json({
        data: req.body
    })
})

app.listen(port, () => console.log(`Server listening on port ${port}!`))

Save the above changes and start the Express app server using Node.

node app.js

You'll be having the REST API endpoint running at http://localhost:3000.

Posting The Form

Once you have a REST API endpoint to make a POST request, let's see how to POST our reactive form to the API.

You need to add a proxy configuration to the Angular app to redirect the API calls request to the Express REST API endpoint. Inside the Angular project folder form-app, add a proxy config file called proxy.conf.json. Here is how it looks:

{
    "/api/*": {
      "target": "http://localhost:3000",
      "changeOrigin": true
    }
  }

The above defined proxy redirects all the /api calls to the application running at http://localhost:3000.

Inside the RootComponent, import the HttpClient to make the API calls.

import { HttpClient } from '@angular/common/http';

Initialize the HttpClient inside the RootComponent constructor method.

constructor(private formBuilder: FormBuilder, private http: HttpClient) { }

Inside the onSubmit method, when the form is valid, you can use the HttpClient to make the POST request to the API endpoint.

  onSubmit(){
    if(this.userForm.valid){
      this.http.post('/api/userCreate', this.userForm.value)
      .subscribe((response)=>{
        console.log('repsonse ',response);
      })
    }
  }

Save the above changes and submit the user form with the valid details filled. You will be able to see the response returned from the REST API endpoint in the browser console.

Conclusion

In this tutorial, you learned how to use Reactive Forms to create a user form in an Angular app. You also saw how to post the reactive form to a REST API endpoint. Hopefully, this will be useful for your current or future Angular web apps.

Also, if you're building applications with sensitive logic, be sure to protect them against code theft and reverse-engineering by following our guide.