Build a Password Strength Checker With Angular
Tags: angular, javascript, forms, reactive
Published: 2019-06-15 13:49:11

---
title: Build a Password Strength Checker With Angular
published: true
description: 
tags: Angular, Javascript, Forms, Reactive
---

In this post, we are going to create a simple form with password input field. We will then add a password strength checker functionality. We are going to add the following rules to the password input form. Password

* Must be at least 6 characters long
* Must contain at least one uppercase letter
* Must contain at least one lowercase letter
* Must contain at least one number
* Must contain at least one special character

We are going to validate each of the rules above using RegExp and then display some color bars to indicate how strong the password is. At the end of the post, we are going to see how to use

* Reactive Forms (In a simple way)
* Component interactions using @Input and @Output decorators
* Colors and bars to represent password strength

Here is how the final app will look like:

![](https://thepracticaldev.s3.amazonaws.com/i/p9o10dc3bsm8utc32ejw.gif)

# Getting Started
First, we are going to create a new project using the Angular CLI by running the command
```js
ng new password-strength
```
In this application, there is no navigation so there is no need to add a routing file.

For simplicity sake, let us install bootstrap 4.
```js
npm install bootstrap
```
Add this 
```js
@import '~bootstrap/dist/css/bootstrap.min.css';
```
to your `styles.scss` or `styles.css` file in the src directory of your project. Note that you can use any other library of your choice for styling the app.

If you are using yarn
```js
yarn add bootstrap
```

## Creating the Form
In the `app.module.ts`, add the import of ReactiveFormsModule
```js
import { ReactiveFormsModule } from '@angular/forms';
```
Then add the ReactiveFormsModule into the imports array
```js
imports: [
    BrowserModule,
    ReactiveFormsModule
]
```
You can use a `Template Driven Form` if you so choose. Here I decided to go with with Reactive Forms.

Now, in the `app.component.html` file, add the html template
```html
<div class="container">
  <div class="row">
      <div class="col mt-5 col-xs-6 col-md-6 col-lg-6">
        <h2>Check Password Strength</h2>
        <br>
      <form>
        <div class="form-group">
          <input type="password" class="form-control" autocomplete="off" placeholder="Password">
        </div>
        <button type="submit" class="btn btn-primary">
          Submit
        </button>
      </form>
    </div>
  </div>
</div>
```
The form contains a password input field. The classes added to the div elements are from bootstrap 4.

In the `app.component.scss` or `app.component.css` depending on what you selected, add to the file
```css
.col {
  margin: 0 auto;
  text-align: center;
}
```
![](https://thepracticaldev.s3.amazonaws.com/i/ffrmnl84nk77tu5a0s2v.PNG)

To use a Reactive Form in Angular, we need to add a `formGroup` property to the form and then add a `formControlName` to the input field.

On the form, add
```js
[formGroup]="passwordForm"
```
So the form looks something like
```html
<form [formGroup]="passwordForm">
    ...
</form>
```

Also, on the password input field, add
```js
formControlName="password"
```
Next, we need to initialize the Reactive form. In the `app.component.ts` file, add the imports
```js
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
```
The `FormGroup` tracks the state of the form-control elements. The `FormBuilder` helps to reduce the boilerplate required to create the form. `Validators` provides some set of built-in validators to be used. We are using the classes so we can initialize the form.

Create a property of type `FormGroup`.
```js
passwordForm: FormGroup;
```
We need the construtor and ngOnInit methods. First, we need to implement the `OnInit` interface and then import from `@angular/core`. The export class line will become
```js
export class AppComponent implements OnInit
```
Add both methods
```js
constructor(private fb: FormBuilder) {}

ngOnInit() {
    this.passwordForm = this.fb.group({
        password: ['', Validators.required],
    });
}
```
In the constructor, the FormBuilder class is injected so that we can use methods available in the class. In the ngOnInit method, the passwordForm is initialized using the FormBuilder and then validating the password field. The key in the object inside the group method must match the `formControlName` in the template. The required validator is added to the input field. Now we have the form and the password field setup. We can now create a new component that will be used to display the password strength.

## Password Strength Component
The password strength component which will be added as a child of the main component will be used to display some bars that will indicate the strength of the password the user types. As the user types into the password field, the bars will automatically be updated with different colors.

To create a new component, we run
```js
ng generate component password-strength
```
This component will be automatically added to the `app.module.ts` file. In the `password-strength.component.html` file, add
```html
<div class="strength">
  <ul class="strengthBar">
    <li class="point" [style.background-color]="bar0"></li>
    <li class="point" [style.background-color]="bar1"></li>
    <li class="point" [style.background-color]="bar2"></li>
    <li class="point" [style.background-color]="bar3"></li>
  </ul>
  <br>
</div>
```

Add these properties to the `password-strength.component.ts` file
```js
bar0: string;
bar1: string;
bar2: string;
bar3: string;
```

In the styles file of the component, add
```css
.strengthBar {
  display: inline;
  list-style: none;
  margin: 0;
  padding: 0;
  vertical-align: 2px;
}

.point:last-of-type {
  margin: 0 !important;
}

.point {
  background: #DDD;
  border-radius: 2px;
  display: inline-block;
  height: 5px;
  margin-right: 1px;
  width: 62px;
}

p {
  font-weight: bold;
  font-size: 20px;
}
```
Go to the `app.component.html` file and add the password-strength component as a child component by using the component selector name `<app-password-strength></app-password-strength>`. The component should be added after the password input field.
```html
<div class="container">
  <div class="row">
      <div class="col mt-5 col-xs-6 col-md-6 col-lg-6">
        <h2>Check Password Strength</h2>
        <br>
      <form [formGroup]="passwordForm">
        <div class="form-group">
          <input type="password" class="form-control" formControlName="password" autocomplete="off" placeholder="Password">
          <app-password-strength></app-password-strength>
        </div>
        <button type="submit" class="btn btn-primary">
          Submit
        </button>
      </form>
    </div>
  </div>
</div>
```

![](https://thepracticaldev.s3.amazonaws.com/i/gqukxleuehqhltdz1mie.PNG)

The component consists of a div with ul and li tags. The li tags represent the bars on the page. As a user types into the input field, the color that will be specified in the component's class will be displayed. Once the password matches all specified characters, the color of all bars will become green.

## Password Strength Functionality
The interaction between the parent and child component will be achieved using the `@Input` decorator. The password from the password form will be bound to an `Input` property coming from the password strength component. There are different ways whereby the data can be intercepted. We are going to intercept the data using the `ngOnChanges` method.

Let us create an input property called `passwordToCheck`
```ts
@Input() public passwordToCheck: string;
```

Then create an array of colors to be displayed on the bars. The number of colors in the array should match the number of bars in the component.
```js
private colors = ['darkred', 'orangered', 'orange', 'yellowgreen'];
```

Now, let us create a method to check the strength of the password. Add the following code
```js
checkStrength(p) {
  // 1
  let force = 0;

  // 2
  const regex = /[$-/:-?{-~!"^_@`\[\]]/g;
  const lowerLetters = /[a-z]+/.test(p);
  const upperLetters = /[A-Z]+/.test(p);
  const numbers = /[0-9]+/.test(p);
  const symbols = regex.test(p);

  // 3
  const flags = [lowerLetters, upperLetters, numbers, symbols];

  // 4
  let passedMatches = 0;
  for (const flag of flags) {
    passedMatches += flag === true ? 1 : 0;
  }

  // 5
  force += 2 * p.length + ((p.length >= 10) ? 1 : 0);
  force += passedMatches * 10;

  // 6
  force = (p.length <= 6) ? Math.min(force, 10) : force;

  // 7
  force = (passedMatches === 1) ? Math.min(force, 10) : force;
  force = (passedMatches === 2) ? Math.min(force, 20) : force;
  force = (passedMatches === 3) ? Math.min(force, 30) : force;
  force = (passedMatches === 4) ? Math.min(force, 40) : force;

  return force;
}
```
First, a property called force of type number is defined which is used as the return type of the method. The value assigned to the property will be used to determine the strength of the password. The 2nd part is where the regular expressions are defined. The regex of special characters, lowercase test, uppercase test, number test and regex test. The 3rd part is an array that contains the regular expressions to be used. In the 4th part, a property called `passedMatches` of type number is defined and its value is incremented inside the loop depending on the regular expression that is satisfied. So, if the first criteria in the flags array is met, the value of `passedMatches` is incremented by 1. If the second criteria is met, the current value is also incremented by 1 until all criterias are met. Otherwise, the value 0 is added. The 5th part checks if the password length is greater than 10 and then multiplies the `passedMatches` value by 10. The 6th part is where the length of the password (which needs to be at least 6 characters) is checked. The 7th part is where the final `force` value is set based on the value of `passedMatches`. Then the force value is returned.

Next we need to bind the `passwordToCheck` input property to the form password. Add `[passwordToCheck]="signupForm.value.password"` to the child component inside `app.component.html`.
```html
<app-password-strength [passwordToCheck]="signupForm.value.password"></app-password-strength>
```
The `passwordToCheck` is the `@Input` property defined in the password strength component. It is bound to the password value from the `formGroup`. So whatever value is stored in the password value field, it will be received in the child component.

Like i said earlier, there are multiple ways the password value can be intercepted in the child component. You can checkout out this [documentation](https://angular.io/guide/component-interaction#pass-data-from-parent-to-child-with-input-binding). We are going to be using the ngOnChanges method to intercept the changes. 

Implement the `OnChanges` interface in the `PasswordStrengthComponent` class and then import the interface from `@angular/core`. Next is to add the method
```js
ngOnChanges(changes: { [propName: string]: SimpleChange }): void {
  const password = changes.passwordToCheck.currentValue;
  this.setBarColors(4, '#DDD');
  if (password) {
    const c = this.getColor(this.checkStrength(password));
    this.setBarColors(c.index, c.color);
  }
}

private getColor(s) {
  let index = 0;
  if (s === 10) {
    index = 0;
  } else if (s === 20) {
    index = 1;
  } else if (s === 30) {
    index = 2;
  } else if (s === 40) {
    index = 3;
  } else {
    index = 4;
  }
  return {
    index: index + 1,
    color: this.colors[index]
  };
}

private setBarColors(count, col) {
  for (let n = 0; n < count; n++) {
    this['bar' + n] = col;
  }
}
```

The `ngOnChanges` method takes in property of type `SimpleChange`. In the SimpleChange property, we have the `passwordToCheck` input property which contains the password's currentValue. As the value changes, the password is intercepted by the ngOnChanges method. The `setBarColors` defined before the if statement is used to set a default color for the bars. If the password is available then the `getColor` method is called and it takes in the `checkStrength` which in turn takes the password as a parameter. Note that the `checkStrength` returns a number which is used in the `getColor`. The `setBarColors` is used to set the colors in the colors array on the bars.

In the `getColor` method, if the return value of the `checkStrength` is equal 10 then we set the index value to zero and so on. Then an object with the index and color is returned. Recall that the bars have a style property with a number appended to the name. E.g: `bar0, bar1, bar2, bar3`. The `setBarColors` is just used to set the colors from the array on the bars.

![](https://thepracticaldev.s3.amazonaws.com/i/27lvks38xkhyuyjft9xi.gif)

We can add more functionalities by displaying a message as the user types and also disabling the submit button unless the password is valid.

### Disable Button
To disable the submit button, we are going to use the `@Output` decorator to send data from child to parent. In this case from the password strength component to the main component.

Add this line to the password strength component class:
```js
@Output() passwordStrength = new EventEmitter<boolean>();
```

Add the `Output` interface and `EventEmiiter` to the `@angular/core` imports. The EventEmitter will emit a boolean value. In this case a true value when the password becomes valid and the emitted value will be used to enable the submit button.

In the `ngOnChanges` method, add the below line into the if statement
```js
const pwdStrength = this.checkStrength(password);
pwdStrength === 40 ? this.passwordStrength.emit(true) : this.passwordStrength.emit(false);
```
Here we are setting the return value of `checkStrength` method to a variable. Then using a ternary operator to emit a boolean value. If pwdStrength is equal to 40 then emit `true`. If the pwdStrength is less than 40 then emit `false`. The line is the same as
```js
if (pwdStrength === 40) {
  this.passwordStrength.emit(true)
} else {
  this.passwordStrength.emit(false)
}
```

The next step is to use this `@Output` eventemitter in the main component. In the component `<app-password-strength></app-password-strength>`, add
```js
(passwordStrength)="passwordValid($event)"
```
which then becomes
```html
<app-password-strength [passwordToCheck]="signupForm.value.password" (passwordStrength)="passwordValid($event)"></app-password-strength>
```

The `passwordStrength` is the output property while `passwordValid($event)` is a method that needs to be defined in the main class component. The `$event` property added as a parameter will contain the emitted boolean value.

Add a new property to the main component's class.
```js
passwordIsValid = false;
```
And also add the `passwordValid` method
```js
passwordValid(event) {
  this.passwordIsValid = event;
}
```
The emitted value from the EventEmitter is set to the `passwordIsValid` property. We can now use this property to disable the button.

On the submit button, add `[disabled]="!passwordIsValid"`.
```html
<button type="submit" class="btn btn-primary" [disabled]="!passwordIsValid">
  Submit
</button>
```
So if the value of `passwordIsValid` is false then the button will be disabled. When the password is valid, the button will be enabled on the page.

![](https://thepracticaldev.s3.amazonaws.com/i/hz2lzr3gqq5w8segtgzx.gif)

The last part to take care of is to add a message as the user types. Create two new variables
```js
msg: string;
msgColor: string;
```
in the password strength component class. Then add a `p` tag after the `ul` tag in the template with the `msg` varaible.
```html
<p [style.color]="msgColor">{{msg}}</p>
```
Inside the if statement in the `ngOnChanges` method, add this switch statement
```js
switch (pwdStrength) {
  case 10:
    this.msg = 'Poor';
    break;
  case 20:
    this.msg = 'Not Good';
    break;
  case 30:
    this.msg = 'Average';
    break;
  case 40:
    this.msg = 'Good';
    break;
}
```
If the `pwdStrength` is 10 then the msg is set equal to `Poor` and so on. So as the user types into the input field, the msg variable is updated. Also, we want to be able to clear the message if the user decides to clear the input field. So add an else part to the if statement and add
```js
this.msg = '';
```
If the input field is empty then the msg should be cleared. In the `getColor` method, add `this.msgColor = this.colors[index]` before the return statement. The method now becomes
```js
private getColor(s) {
  ...
  this.msgColor = this.colors[index];
  ...
}
```

![](https://thepracticaldev.s3.amazonaws.com/i/p9o10dc3bsm8utc32ejw.gif)

# Conclusion
So far we have been able to add the password strength functionality. We saw how to use Reactive Forms in Angular, @Input and @Output decorators for component interactions. You can add more regular expression validations to the password.

[Find the github repo for the sample app here](https://github.com/uzochukwueddie/password-strength).

If you are interested in more Angular related stuff, you can follow me [Twitter](https://twitter.com/uzochukwueddie) and also subscribe to my [YouTube channel](https://www.youtube.com/channel/UCqTEGhqVPcjfhs7_bQjnoRA/videos?view_as=subscriber).