Search code examples
angulartypescriptangular-reactive-formslibphonenumberangular-validation

Use google-libphonenumber in angular reactive forms validator


This is a basic use case for using this library. I need to verify the number if it is valid. I use angular reactive forms custom validators.
Validator is in file: validators/phone-number.validator.ts
First step is to get google-libphonenumber PhoneNumberUtil instance

Current state of my code is:

import { ValidatorFn, AbstractControl } from '@angular/forms';
import phoneUtil = require('google-libphonenumber');
const phoneUtilInstance = phoneUtil.PhoneNumberUtil.getInstance();

export function PhoneNumberValidator(): ValidatorFn {
  return (control: AbstractControl): { [key: string]: any } => {
    if (!phoneUtilInstance.isValidNumber(control.value)) {
      return { 'wrongNumber': { value: control.value } };
    }
    return null;
  }
}

Usage in reactive form (file contact.component.ts):

import { PhoneNumberValidator } from '@app/validators';
...
ngOnInit(): void { ...
this.editPhoneForm = this.formBuilder.group({
  id: [''],
  phone: ['', [
    Validators.minLength(3),
    PhoneNumberValidator()
  ]],
}); ...

This code can be build and executed, however, after launch I get:

ERROR TypeError: a.getCountryCodeOrDefault is not a function
at i18n.phonenumbers.PhoneNumberUtil.getRegionCodeForNumber (VM145038 libphonenumber.js:4418)

How to properly use this library in the Angular project as a validator?

Declaration
This question is similar to How to use Google libphonenumber in Typescript? but in this case it is specifically about the Angular project.


Solution

  • I have found a solution currently:

    1. You need google-libphonenumber and also types for it:
      npm install --save google-libphonenumber
      npm install --save-dev @types/google-libphonenumber

    2. Import PhoneNumberUtil, PhoneNumber into your validator file (full content):

    import { ValidatorFn, AbstractControl } from '@angular/forms';
    import { PhoneNumberUtil, PhoneNumber } from 'google-libphonenumber';
    
    const phoneNumberUtil = PhoneNumberUtil.getInstance();
    
    export function PhoneNumberValidator(regionCode: string = undefined): ValidatorFn {
      return (control: AbstractControl): { [key: string]: any } => {
        let validNumber = false;
        try {
          const phoneNumber = phoneNumberUtil.parseAndKeepRawInput(
            control.value, regionCode
          );
          validNumber = phoneNumberUtil.isValidNumber(phoneNumber);
        } catch (e) { }
    
        return validNumber ? null : { 'wrongNumber': { value: control.value } };
      }
    }
    
    1. Use PhoneNumberValidator in reactive form with your default region code (part of code):
    import { PhoneNumberValidator } from '@app/validators';
    ...
    ngOnInit(): void { ...
    this.editPhoneForm = this.formBuilder.group({
      id: [''],
      phone: ['', [
        PhoneNumberValidator('US')
      ]],
    }); ...