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:
-
On the UI, the country code appears twice: once in the dial code
dropdown and again in the phone number field. Example: +91 appears in
the dropdown and +919876543210 appears in the input field. -
The phone number is not formatted automatically based on the selected
country. Example: When I select the US as the country, it doesn’t
format the number as (201)-555-1234.
Attempts:
- I’ve tried setting the value property of the FormControl explicitly.
- Ensured
ngx-intl-tel-input
configuration matches the documentation.
How can I fix these issues so that:
- The country code does not appear twice.
- The phone number is automatically formatted based on the selected country?
Any guidance would be appreciated!
2
Answers
Try setting up PhoneNumberFormat to
E164
. Also a working stackblitz will help debug and provide a quick solution to it.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:
Something like:
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).