intl_phone_number_input icon indicating copy to clipboard operation
intl_phone_number_input copied to clipboard

Initial value overrides selected country

Open assemblical opened this issue 3 years ago • 11 comments

Describe the bug Selecting a country in the dialog (PhoneInputSelectorType.DIALOG) gets reset by the initial value after selection.

Package version ^0.7.0+1

Flutter version ^2.0.4

To Reproduce Steps to reproduce the behavior:

  1. Open the dialog to choose a country.
  2. Input a few letters to search for a country.
  3. Select a country.
  4. The country selection gets reset to the initial value.

All interactions that lead to a call to didUpdateWidget() should lead to the behavior.

Expected behavior Keep the selected country.

Additional context The problem is the call to loadCountries() in didUpdateWidget. It is assumed that the initialValue changed when its hash changed if (oldWidget.initialValue?.hash != widget.initialValue?.hash) which is not correct to my mind. A new object with the same content will always have a new hash? As a new country was selected if (country!.alpha2Code != widget.initialValue?.isoCode) evaluates to true and calls loadCountries() without the previouslySelectedCountry argument (therefore null), resetting the country to the initial value in void loadCountries({Country? previouslySelectedCountry}): Country country = previouslySelectedCountry ?? Utils.getInitialSelectedCountry( countries, widget.initialValue?.isoCode ?? '', );.

assemblical avatar Apr 18 '21 10:04 assemblical

replace

if (oldWidget.initialValue?.hash != widget.initialValue?.hash)

with

if (oldWidget.initialValue?.isoCode != widget.initialValue?.isoCode)

has fixed

LuisAkamala avatar Apr 30 '21 07:04 LuisAkamala

This just happened to me. The fix with the current version of the package is to update the initialValue variable in the onChanged function. Seems like in the code the initialValue is not being used only when building the widget for the first time, but also when updating.

luis721 avatar May 27 '21 23:05 luis721

Hey! Are there any updates on this?

masteradit avatar Jul 24 '21 18:07 masteradit

Is there an update with the fix ?

Coder-Manuel avatar Aug 07 '21 09:08 Coder-Manuel

This is happening to me when I instance a new object directly in the widget just like this:
initialValue: PhoneNumber(isoCode: 'IQ'), So I just extract it to variable and its work fine

MahmoodAliL avatar Aug 13 '21 10:08 MahmoodAliL

This issue is fixed. please use it correctly

If You are using it in stateless widget declare global variable in controller like below I have created global var in controller class

class AuthController extends GetxController {
.
.
.
PhoneNumber phoneNumber = PhoneNumber(isoCode: 'IN');
.
.
.
}

And in Stateless widget

InternationalPhoneNumberInput(
.
.
.                    
initialValue: authController.phoneNumber,
.
.
. 
)

sugatmankar avatar Aug 14 '21 14:08 sugatmankar

This issue is fixed. please use it correctly

While your workaround works fine a fix would be to use operator == instead of the hash for comparing the intial value as PhoneNumber inherits Equatable and correctly overrides @override List<Object?> get props => [phoneNumber, isoCode, dialCode]; anyways?

assemblical avatar Aug 14 '21 16:08 assemblical

This issue is fixed. please use it correctly

While your workaround works fine a fix would be to use operator == instead of the hash for comparing the intial value as PhoneNumber inherits Equatable and correctly overrides @override List<Object?> get props => [phoneNumber, isoCode, dialCode]; anyways?

For both Stateless and Statefull widgets?

sugatmankar avatar Aug 14 '21 17:08 sugatmankar

For both Stateless and Statefull widgets?

Most of the times clients will use this dialog to update some UI component (e.g. text field) with the selected country code therefore using a stateful widget. It's not wrong usage to declaratively state an initialValue to my mind (The quite high amount of people still participating or filing bug reports to this issue seem to agree with me). I don't know the implementation details of this plugin and which member instances you have to update but you have the information that the initial value didn't change by using operator == and therefore don't need to always override the selected country when used within a stateful widget.

assemblical avatar Aug 15 '21 09:08 assemblical

It just got another idea that improves the api. Most people probably want to use the country code from the system settings as initial value. Therefore exposing a bool property e.g. 'useSystemLocaleAsInitialValue' would probably be sufficient for a lot (most?) clients.

assemblical avatar Aug 15 '21 09:08 assemblical

just adding my voice to this issue, to confirm that it hit me in production T_T

xEyad avatar Feb 14 '22 18:02 xEyad