In this 2nd part of our tutorial, we are going to continue our journey of creating reset password functionality. In the , we completed the back-end with Node.js Express and Node mailer, created an API which will use in this part in Angular. Let’s get started. 1st part Creating a new angular project Let’s create a new project and run it. ng angular- - new reset password cd angular- - reset password ng serve We are going to have several pages so need to create an app-routing.module.ts for navigating needed pages in our site, { NgModule } ; {Routes, RouterModule} ; { SigninComponent } ; { SignupComponent } ; { RequestResetComponent } ; { ResponseResetComponent } ; routes: Routes = [ { : , : SigninComponent, }, { : , : SignupComponent, }, { : , : RequestResetComponent, }, { : , : ResponseResetComponent }, { : , : } ]; @NgModule({ : [RouterModule.forRoot(routes)], : [RouterModule] }) {} import from '@angular/core' import from '@angular/router' import from './components/signin/signin.component' import from './components/signup/signup.component' import from './components/request-reset/request-reset.component' import from './components/response-reset/response-reset.component' const path 'sign-in' component path 'sign-up' component path 'request-reset-password' component path 'response-reset-password/:token' component path '**' redirectTo 'sign-in' imports exports export class MainRoutingModule The names of each rout already makes it easier to understand which rout for what should be used. You may also notice that includes a response-reset-password :token That's the that we send via email in the back-end attached to the URL. However before creating the components for each rout we need to generate an Angular service where we will use our API from the first part. resettoken Creating an Auth service ng generate auth service Let’s update our service file: { Injectable } ; { HttpClient } ; { Observable } ; BASEURL = ; @Injectable({ : }) { (private http: HttpClient) { } registerUser(body): Observable<any> { .http.post( , body); } loginUser(body): Observable<any> { .http.post( , body); } requestReset(body): Observable<any> { .http.post( , body); } newPassword(body): Observable<any> { .http.post( , body); } ValidPasswordToken(body): Observable<any> { .http.post( , body); } } import from '@angular/core' import from '@angular/common/http' import from 'rxjs' const 'http://localhost:3000/api/resetpassword' providedIn 'root' export class AuthService constructor return this ` /register` ${BASEURL} return this ` /login` ${BASEURL} return this ` /req-reset-password` ${BASEURL} return this ` /new-password` ${BASEURL} return this ` /valid-password-token` ${BASEURL} The last is for validating the token and checking if it’s still active. Other ones looks very descriptive. It’s time to create the components. ValidPasswordToken Creating a Signup component It’s time to make Signup component functional. { Component, OnInit } ; { FormBuilder, FormGroup, Validators } ; { AuthService } ; { Router } ; @Component({ : , : , : [ ] }) { SignupForm: FormGroup; forbiddenEmails: any; errorMessage: string; ( private fb: FormBuilder, private authService: AuthService, private router: Router, ) { .buildSignupForm(); } ngOnInit() { } private buildSignupForm() { .SignupForm = .fb.group({ : [ , [Validators.required]], : [ , [Validators.required, Validators.email], .forbiddenEmails], : [ , [Validators.required, Validators.minLength( )]], }); } onSubmit() { .SignupForm.reset(); } signupUser() { .authService.registerUser( .SignupForm.value).subscribe( { .SignupForm.reset(); setTimeout( { .router.navigate([ ]); }, ); }, err => { (err.error.msg) { .errorMessage = err.error.msg[ ].message; } (err.error.message) { .errorMessage = err.error.message; } } ); } } import from '@angular/core' import from '@angular/forms' import from '../../services/auth.service' import from '@angular/router' selector 'app-signup' templateUrl './signup.component.html' styleUrls '../signin/signin.component.css' export class SignupComponent implements OnInit constructor this this this username null email null this password null 4 this this this => data this => () this 'sign-in' 3000 if this 0 if this As you see it’s just a simple reactive form supported by Angular. We also created function for sending the data into the server and creating the user. Let’s create an HTML template for this component. SignupUser() Sign Up {{errorMessage}} Please enter a valid username! Please enter a valid email! Password is required and must have more than 4 characters! Sign Up < = > div class "container-fluid form" < = > div class "row form-row " < = > div class "col-sm-9 col-md-7 col-lg-5 mx-auto" < = > div class "card my-5" < = > div class "card-body" < = > h5 class "card-title text-center" </ > h5 < > div < = * = > div id "errorMsg" ngIf "errorMessage" < > span </ > span </ > div < = [ ]= ( )= > form action "" formGroup "SignupForm" ngSubmit "signupUser()" < = > div class "form-group form-signup" < = = = = = = /> input _ngcontent-c0 "" class "form-control form-control-lg" placeholder "Username" type "text" id "username" formControlName "username" < * = = > span ngIf "!SignupForm.get('username').valid && SignupForm.get('username').touched" class "help-block" </ > span </ > div < = > div class "form-group" < = = = = = = /> input _ngcontent-c0 "" class "form-control form-control-lg" placeholder "E-mail" type "text" id "email" formControlName "email" < * = = > span ngIf "!SignupForm.get('email').valid && SignupForm.get('email').touched" class "help-block" </ > span </ > div < = > div class "form-group" < = = = = /> input class "form-control form-control-lg" placeholder "Password" type "password" formControlName "password" < * = = > span ngIf "!SignupForm.get('password').valid && SignupForm.get('password').touched" class "help-block" </ > span </ > div < = > div class "form-group" < = = ( )= > button type "submit" class " btn btn-primary" ngSubmit "signupUser()" </ > button </ > div </ > form </ > div </ > div </ > div </ > div </ > div </ > div It will look like this: You can style it as you wish. This tutorial is mainly about functional part and we will not spend time on CSS. That’s it. Let's create a Forgot password component where we should submit our email for receiving a link in our inbox containing a link to new page where we can change our password. Creating RequestReset Component Nothing special will be in this component. We just will create another Angular reactive form that will check if the email is valid and then will use RequestResetUser function for sending the data. () { Component, OnInit } ; { FormGroup, Validators, FormControl } ; { AuthService } ; { Router } ; @Component({ : , : , }) { RequestResetForm: FormGroup; forbiddenEmails: any; errorMessage: string; successMessage: string; IsvalidForm = ; ( private authService: AuthService, private router: Router, ) { } ngOnInit() { .RequestResetForm = FormGroup({ : FormControl( , [Validators.required, Validators.email], .forbiddenEmails), }); } RequestResetUser(form) { .log(form) (form.valid) { .IsvalidForm = ; .authService.requestReset( .RequestResetForm.value).subscribe( { .RequestResetForm.reset(); .successMessage = ; setTimeout( { .successMessage = ; .router.navigate([ ]); }, ); }, err => { (err.error.message) { .errorMessage = err.error.message; } } ); } { .IsvalidForm = ; } } } import from '@angular/core' import from '@angular/forms' import from '../../services/auth.service' import from '@angular/router' selector 'app-request-reset' templateUrl './request-reset.component.html' export class RequestResetComponent implements OnInit true constructor this new 'email' new null this console if this true this this => data this this "Reset password link send to email sucessfully." => () this null this 'sign-in' 3000 if this else this false HTML template of this component will be almost the same as for component. SignUp Forgot Password {{errorMessage}} {{successMessage}} Please enter a valid email! Reset Password < = > div class "container-fluid form" < = > div class "row form-row " < = > div class "col-sm-9 col-md-7 col-lg-5 mx-auto" < = > div class "card my-5" < = > div class "card-body" < = > h5 class "card-title text-center" </ > h5 < > div < = * = > div id "errorMsg" ngIf "errorMessage" < > span </ > span </ > div < = * = > div id "successMsg" ngIf "successMessage" < > span </ > span </ > div < = [ ]= ( )= > form action "" formGroup "RequestResetForm" ngSubmit "RequestResetUser(RequestResetForm)" < = > div class "form-group" < = = = = = = /> input _ngcontent-c0 "" class "form-control form-control-lg" placeholder "email" type "text" id "email" formControlName "email" < * = = > span ngIf "!RequestResetForm.get('email').valid && !IsvalidForm" class "help-block" </ > span </ > div < = > div class "form-group" < > div < = = > button type "submit" class " btn btn-primary" </ > button </ > div </ > div </ > form </ > div </ > div </ > div </ > div </ > div Here is how will it look like: The last component that we are going to build is component. ResponseReset Creating ResponseReset Component This page will be navigated from your email that includes the URL with token. Let’s get started: { Component, OnInit } ; { FormBuilder, FormGroup, Validators } ; { AuthService } ; { Router, ActivatedRoute } ; @Component({ : , : , }) { ResponseResetForm: FormGroup; errorMessage: string; successMessage: string; resetToken: ; CurrentState: any; IsResetFormValid = ; ( private authService: AuthService, private router: Router, private route: ActivatedRoute, private fb: FormBuilder ) { .CurrentState = ; .route.params.subscribe( { .resetToken = params.token; .log( .resetToken); .VerifyToken(); }); } ngOnInit() { .Init(); } VerifyToken() { .authService.ValidPasswordToken({ : .resetToken }).subscribe( { .CurrentState = ; }, err => { .CurrentState = ; } ); } Init() { .ResponseResetForm = .fb.group( { : [ .resetToken], : [ , [Validators.required, Validators.minLength( )]], : [ , [Validators.required, Validators.minLength( )]] } ); } Validate(passwordFormGroup: FormGroup) { new_password = passwordFormGroup.controls.newPassword.value; confirm_password = passwordFormGroup.controls.confirmPassword.value; (confirm_password.length <= ) { ; } (confirm_password !== new_password) { { : }; } ; } ResetPassword(form) { .log(form.get( )); (form.valid) { .IsResetFormValid = ; .authService.newPassword( .ResponseResetForm.value).subscribe( { .ResponseResetForm.reset(); .successMessage = data.message; setTimeout( { .successMessage = ; .router.navigate([ ]); }, ); }, err => { (err.error.message) { .errorMessage = err.error.message; } } ); } { .IsResetFormValid = ; } } } import from '@angular/core' import from '@angular/forms' import from '../../services/auth.service' import from '@angular/router' selector 'app-request-reset' templateUrl './response-reset.component.html' export class ResponseResetComponent implements OnInit null true constructor this 'Wait' this => params this console this this this this resettoken this => data this 'Verified' this 'NotVerified' this this resettoken this newPassword '' 4 confirmPassword '' 4 const const if 0 return null if return doesNotMatch true return null console 'confirmPassword' if this true this this => data this this => () this null this 'sign-in' 3000 if this else this false Firstly it verifies the token then just compares 2 passwords to see if they match and as the last step it sends the updated password to the back-end. That’s it! We can create a HTML template for it. Please Wait... Invalid URL. Set New Password {{errorMessage}} {{successMessage}} Password is required with atleast 4 characters. . Confirm Password does not match with password. Update Password < = > div class "container-fluid form" < = * = > div class "row" ngIf "CurrentState=='Wait'" < = > div class "col-md-12 close-form" < > h2 </ > h2 </ > div </ > div < = * = > div class "row" ngIf "CurrentState=='NotVerified'" < = > div class "col-md-12" < > h2 </ > h2 </ > div </ > div < = * = > div class "row" ngIf "CurrentState=='Verified'" < = > div class "col-sm-9 col-md-7 col-lg-5 mx-auto" < = > div class "card card-signin my-5" < = > div class "card-body" < = > h5 class "card-title text-center" </ > h5 < > div < = * = > div id "errorMsg" ngIf "errorMessage" < > span </ > span </ > div < = * = > div id "successMsg" ngIf "successMessage" < > span </ > span </ > div < = [ ]= ( )= > form action "" formGroup "ResponseResetForm" ngSubmit "ResetPassword(ResponseResetForm)" < = > div class "form-group" < = = = = = = /> input _ngcontent-c0 "" class "form-control form-control-lg" placeholder "Password" type "password" id "password" formControlName "newPassword" < * = = > span ngIf "!ResponseResetForm.get('newPassword').valid && !IsResetFormValid" class "help-block" </ > span </ > div < = > div class "form-group" < = = = = = = /> input _ngcontent-c0 "" class "form-control form-control-lg" placeholder "Confirm Password" type "password" id "cpassword" formControlName "confirmPassword" < * = = > span ngIf "!ResponseResetForm.get('confirmPassword').valid && !IsResetFormValid" class "help-block" </ > span < * = = > span ngIf "ResponseResetForm.get('confirmPassword').valid && (ResponseResetForm.get('confirmPassword').value != ResponseResetForm.get('newPassword').value) && !IsResetFormValid" class "help-block" </ > span </ > div < = > div class "form-group" < > div < = = > button type "submit" class " btn btn-primary" </ > button </ > div </ > div </ > form </ > div </ > div </ > div </ > div </ > div Based on condition it shows the right part of the template. Here is how it will look like: That’s all! Hope this tutorial was helpful for you. Also don’t forget to include components in app.module.ts Conclusion You can get the full source code here: Github