libphonenumber-js icon indicating copy to clipboard operation
libphonenumber-js copied to clipboard

Feature request: expose a function to convert CountryCallingCode to CountryCode, or expose MetadataJson value

Open bbarry opened this issue 3 years ago • 13 comments

There is a function exposed getCountryCallingCode(countryCode: CountryCode): CountryCallingCode) but no inverse of this function:

export function getAllCountryCodes(countryCallingCode: CountryCallingCode): CountryCode[] | undefined {
    return metadata.country_calling_codes[countryCallingCode];
}

This would be useful if you are trying to use any of the functionality that uses CountryCode but your dataset happens to have a calling code separate from the numbers but no country data.

Alternatively exposing the built in metadata would allow users to do this ourselves. An implementation I am playing with today needs this function in order to figure out which parameters are needed to pass to parsePhoneNumber to handle a large amount of questionably formatted data. I've resorted to:

const phoneMetadata: Record<string, any> = new Metadata();
let metadataJson: MetadataJson | undefined = undefined;
if ('metadata' in phoneMetadata) {
  metadataJson = phoneMetadata.metadata;
}
if (!metadataJson) {
  throw new Error(
    'libphonenumber-js implementation changed; figure out new way to get country codes from country calling codes'
  );
}

to write the above function...

bbarry avatar Feb 03 '22 20:02 bbarry

Use a combination of getCountries() and getCountryCallingCode() to build an initial map of calling code to countries. It’s not clear what exactly you request.

On Thu, 3 Feb 2022 at 23:39, Bill Barry @.***> wrote:

There is a function exposed getCountryCallingCode(countryCode: CountryCode): CountryCallingCode) but no inverse of this function:

export function getAllCountryCodes(countryCallingCode: CountryCallingCode): CountryCode[] | undefined { return metadata.country_calling_codes[countryCallingCode];}

This would be useful if you are trying to use any of the functionality that uses CountryCode but your dataset happens to have a calling code separate from the numbers but no country data.

Alternatively exposing the built in metadata would allow users to do this ourselves. An implementation I am playing with today needs this function in order to figure out which parameters are needed to pass to parsePhoneNumber to handle a large amount of questionably formatted data. I've resorted to:

const phoneMetadata: Record<string, any> = new Metadata();let metadataJson: MetadataJson | undefined = undefined;if ('metadata' in phoneMetadata) { metadataJson = phoneMetadata.metadata;}if (!metadataJson) { throw new Error( 'libphonenumber-js implementation changed; figure out new way to get country codes from country calling codes' );}

to write the above function...

— Reply to this email directly, view it on GitHub https://github.com/catamphetamine/libphonenumber-js/issues/420, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADUP355LY5KMD7KZS6GYIDUZLRZFANCNFSM5NP7KXGQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you are subscribed to this thread.Message ID: @.***>

catamphetamine avatar Feb 03 '22 22:02 catamphetamine

I think he meant for cases like multiple countries for one country calling code we need a function to extract those countries (that's my case).

Example for country calling code +44, we could have a function like this: const countryList = libPhoneNumber.getCountriesByCallingCode(44)

And in countryList we would have : ['GB', 'GG', 'IM', 'JE']

awcs avatar Nov 29 '22 15:11 awcs

Multiple countries can be associated with a given calling code.

Giving a calling code parsed from phone number string, the country may be ambiguous.

In this case, PhoneNumber.country is undefined.

There is a one to many mapping CountryCallingCode -> CountryCode.

The best we can do as awcs mentioned, is get the list of countries associated with that country.

In our case, we just default to the first country associated with the calling code; the metadata seems to be organized in such a way that the most prominent countries are first in the lists.

  const code =
    parsedPhoneNumber.country ??
    _.get(parsedPhoneNumber, ['metadata', 'country_calling_codes', parsedPhoneNumber.countryCallingCode, '0'])

rwev avatar Dec 21 '22 19:12 rwev

@rwev I don't really see a scenario in which a person would want to somehow use the list of countries corresponding to a specific country calling code. Could you provide one?

catamphetamine avatar Dec 21 '22 19:12 catamphetamine

In any case, one could also use the Metadata class and then inspect its methods. For example, this one: https://gitlab.com/catamphetamine/libphonenumber-js/-/blob/26b50cdd5c61416ebd12bcbc77045bfe400bb28d/source/metadata.js#L99

catamphetamine avatar Dec 21 '22 20:12 catamphetamine

It actually says it at the end of the readme section: https://gitlab.com/catamphetamine/libphonenumber-js#programmatic-access

As one can see, the Metadata class is not documented much. Partially, that's because its usage is not necessarily encouraged, but it's still used, for example, in react-phone-number-input to get "leading digits" for a country, or to get maximum phone number length for a country. Stick to the methods documented above, don't call any other methods. If you think there's a need to call any other methods, create a discussion issue.As one can see, the Metadata class is not documented much. Partially, that's because its usage is not necessarily encouraged, but it's still used, for example, in react-phone-number-input to get "leading digits" for a country, or to get maximum phone number length for a country. Stick to the methods documented above, don't call any other methods. If you think there's a need to call any other methods, create a discussion issue.

catamphetamine avatar Dec 21 '22 20:12 catamphetamine

So if someone provides a sensible use case for a getCountryCodesForCallingCode() method then I'd include it in the readme.

catamphetamine avatar Dec 21 '22 20:12 catamphetamine

A phone number input in which the user can select a country.

https://dribbble.com/shots/15474151-Phone-Number-Input-Field-Exploration

Determining the country code from the selected country is easily done via getCountryCallingCode

Repopulating the input from the final phone number is where the problem arises, as the parsed countryCallingCode does not determine the original country.

Classic problem of reversing a many -> one calculation (i.e. one -> many)

rwev avatar Dec 21 '22 20:12 rwev

If a phone number belongs to any country, its ‘country’ will be set. Otherwise, the country is unknown

On Wed, 21 Dec 2022 at 23:23, rwev @.***> wrote:

A phone number input in which the user can select a country.

https://dribbble.com/shots/15474151-Phone-Number-Input-Field-Exploration

Determining the country code from the selected country is easily done via getCountryCallingCode

Repopulating the input from the final phone number is where the problem arises, as the parsed countryCallingCode does not determine the original country.

Classic problem of reversing a many -> one calculation (i.e. one -> many)

— Reply to this email directly, view it on GitHub https://github.com/catamphetamine/libphonenumber-js/issues/420#issuecomment-1362054327, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADUP33P6VVDTL3EPR234WLWONRL5ANCNFSM5NP7KXGQ . You are receiving this because you commented.Message ID: @.***>

catamphetamine avatar Dec 21 '22 20:12 catamphetamine

There's a difference between "the country is unknown" and "there are multiple countries available"... Some phone number can belong to multiple country as i explained in my first comment.

Access metadata, which are not typed btw, seems a little bit random.

awcs avatar Jan 06 '23 15:01 awcs

There's a difference between "the country is unknown" and "there are multiple countries available"...

No. "Country is unknown" means exactly that.

Some phone number can belong to multiple country as i explained in my first comment.

No it can't

catamphetamine avatar Jan 06 '23 23:01 catamphetamine

Access metadata, which are not typed btw, seems a little bit random.

Metadata is perfectly typed and accessing it is in no way random.

catamphetamine avatar Jan 06 '23 23:01 catamphetamine

Published [email protected]:

Added PhoneNumber.getPossibleCountries() function. It returns a list of countries this phone number could possibly belong to. Can be used when parsing complete international phone numbers containing a "calling code" that is shared between several countries. If parsing such a phone number returns country: undefined then getPossibleCountries() function could be used to somehow speculate about what country could this phone number possibly belong to.

catamphetamine avatar Jan 08 '23 11:01 catamphetamine