Use google-libphonenumber in angular reactive forms validator
Asked Answered
A

1

9

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.

Anastasia answered 28/3, 2018 at 8:50 Comment(0)
A
21

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')
  ]],
}); ...
Anastasia answered 28/3, 2018 at 9:45 Comment(3)
Can you demonstrate this in code demo -- stackblitzLongs
This answer works really well except that it effectively acts as a "required" validator as well (which it shouldn't IMO) - it should first test the control.value is not empty and if it is empty it should return null (valid) - you can then combine it with a Validators.required validator if it also needs to be required.Thiosinamine
Optional param can be used: PhoneNumberValidator(regionCode?: string):Maximinamaximize

© 2022 - 2024 — McMap. All rights reserved.