tyler
tyler

Reputation: 311

How to resolve duplicate country code and automatic formatting issues with ngx-intl-tel-input in Angular?

I'm using the ngx-intl-tel-input library in my Angular project to handle phone number input fields. I've created a reusable component for the phone number field, and I am passing a FormControl from the parent component to it.

Here is my code:

component.ts

import { Component, Input } from '@angular/core';
import { FormControl } from '@angular/forms';
import { CountryISO, PhoneNumberFormat, SearchCountryField } from 'ngx-intl-tel-input';

@Component({
  selector: 'app-new-phone-no-field-v1',
  templateUrl: './new-phone-no-field-v1.component.html',
  styleUrl: './new-phone-no-field-v1.component.css'
})
export class NewPhoneNoFieldV1Component {
  @Input() control!: FormControl;
  @Input() separateDialCode: boolean = false;
  @Input() maxLength: number = 15;
  @Input() phoneValidation: boolean = true;

  preferredCountries: CountryISO[] = [
    CountryISO.UnitedStates,
    CountryISO.UnitedKingdom,
    CountryISO.India,
    CountryISO.Australia,
    CountryISO.Philippines,
    CountryISO.Thailand,
    CountryISO.SouthAfrica,
    CountryISO.Panama,
    CountryISO.Mexico,
    CountryISO.Indonesia,
    CountryISO.Canada,
    CountryISO.DominicanRepublic,
  ];
  searchCountryField: SearchCountryField[] = [
    SearchCountryField.Iso2,
    SearchCountryField.Name
  ];
  phoneNumberFormat: PhoneNumberFormat = PhoneNumberFormat.National;
  selectedCountryISO: CountryISO = CountryISO.UnitedStates;
}

Component.html

<div class="intl-tel-input-wrapper">
    <ngx-intl-tel-input
      [cssClass]="'custom'"
      [onlyCountries]="preferredCountries"
      [enableAutoCountrySelect]="true"
      [enablePlaceholder]="true"
      [searchCountryFlag]="true"
      [searchCountryField]="searchCountryField"
      [selectFirstCountry]="false"
      [selectedCountryISO]="selectedCountryISO"
      [maxLength]="maxLength"
      [phoneValidation]="phoneValidation"
      [separateDialCode]="true"
      [numberFormat]="phoneNumberFormat"
      name="phone"
      [formControl]="control">
    </ngx-intl-tel-input>
    <div *ngIf="control.touched && control.invalid" class="error-messages">
      <div *ngIf="control.errors?.required">Phone number is required.</div>
      <div *ngIf="!control.errors?.validatePhoneNumber?.valid">Invalid phone number.</div>
    </div>
  </div>
  

Parent.component.html

<app-new-phone-no-field-v1 
  [control]="$any(userForm.get('phone'))"
  [separateDialCode]="true">
</app-new-phone-no-field-v1>

<div class="error error-msg">
  <div *ngIf="f.phone.errors?.required">
    Phone Number is required.
  </div>
  <div *ngIf="f.phone.errors?.pattern">
    Phone Number is invalid.
  </div>
</div>

API Data: The API returns phone numbers in the format: +919876543210. I'm patching this data to the form using:

this.userForm.patchValue({ phone: data.phone });

Issues:

Attempts:

How can I fix these issues so that:

Image1

Image2

Upvotes: 0

Views: 75

Answers (2)

Misha Mashina
Misha Mashina

Reputation: 2113

So you're getting the country code as part of the phone number from API, and you also have separate dial code displayed? Then it seems to me that you have to force the plugin to re-handle the data you patch it, since it won't do it on its own:

  • patch the form with the value as you are already doing,
  • the plugin will generate the nationalNumber (like (201)-555-1234) and dialCode (like +1) values based on its own handling of the input value,
  • patch the form with the nationalNumber value: it will now display the format you want with the stripped country code.

Something like:

evilPluginPusher(dataPhone:string) { // call it by passing your data.phone value
   this.userForm.controls['phone'].patchValue(dataPhone); 
   this.userForm.updateValueAndValidity();
   setTimeout(() => {
      let formatedNumber = this.userForm.controls['phone'].value.nationalNumber;
      this.userForm.controls['phone'].patchValue(formatedNumber);
      this.userForm.updateValueAndValidity();
   }, 1); // any duration over 0
}

Yeah it has a setTimeout, so in a split second you'll see the default value/country in the input. You can always use css to hide the element and use some var flag to trigger displaying the element when final patch has been done. The form just has to be there to be patched, and the plugin has to do its thing to get the nationalNumber, so no use in putting the whole element into ngIf.

Stackblitz example here (I've put 3 different national numbers to test with).

Upvotes: 0

Bharat Nagdev
Bharat Nagdev

Reputation: 36

Try setting up PhoneNumberFormat to E164. Also a working stackblitz will help debug and provide a quick solution to it.

Upvotes: 1

Related Questions