intl_phone_number_input
intl_phone_number_input copied to clipboard
Error when using PhoneNumberInput initial value in stateful widget
Hi there,
Describe the bug The bug is that I am not able to change the contents of the input field when the two following conditions are met:
- I call
setState((){});
in theonChanged
parameter, and - I provide
initialValue: PhoneNumber(phoneNumber: "+447835201980", isoCode: "GB")
to the input field. If I remove either of these conditions, the code works fine.
Package version intl_phone_number_input: ^0.7.0+2
Flutter version 2.10.4
To Reproduce Steps to reproduce the behavior:
- Code Snippet
import 'package:flutter/material.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
var darkTheme = ThemeData.dark().copyWith(primaryColor: Colors.blue);
return const MaterialApp(
title: 'Demo',
home: Scaffold(
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Center(
child: InternationalPhoneNumberInput(
onInputChanged: (PhoneNumber number) {
setState(() {});
print("input apparently changed");
print(number.phoneNumber);
},
initialValue: PhoneNumber(
phoneNumber: "+447862792432",
isoCode: "GB",
),
),
);
}
}
- Use case
My original use case is to have a button that is greyed out (not clickable) based the number's value (like if the phone number is blank) and have it be clickable on other occasions. However
- Interaction with the widget
The only interaction with the widget required to see the bug is to try inputting numbers on it with the above code.
- See error 5 ...
Expected behavior I expected to be able to input numbers.
Screenshots If applicable, add screenshots to help explain your problem.
** Targeted platforms (please complete the following information):**
- OS [e.g. Android, iOS, ...]
- I have tested the Android emulator only.
- Web [✔ or ❌]
- I have not tested on the web. ❌
Additional context I actually moved my form data to flutter_redux for an easier-to-handle architecture and had the same problem there when wrapping the PhoneNumberInput in a StoreConnector.
However, I managed to patch my way through that bug by using ignoreChange: (_) => true,
for the StoreConnector widget directly above the . So it's not an issue for me anymore, but I thought it might be worth filing a bug in case any other person comes across this and the team behind this project think it is worth addressing the setState/initialValue bug.
For reference (in case anyone else comes across this via Google), my working widget with flutter_redux:
import 'package:carrybags_partner_app/redux/app_state/app_state.dart';
import 'package:carrybags_partner_app/redux/form_reducers/profile_form_reducer.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:intl_phone_number_input/intl_phone_number_input.dart';
class ProfileFormPhone extends StatelessWidget {
const ProfileFormPhone({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ColoredBox(
color: Colors.white,
child: StoreConnector<AppState, AppState>(
ignoreChange: (_) => true,
onInit: (store) async {
final String number = store.state.profile.phoneNumber.toString();
final PhoneNumber tempNum =
await PhoneNumber.getRegionInfoFromPhoneNumber(number);
final PhoneNumber phoneNumber =
store.state.profileForm!.phoneNumber ?? tempNum;
store.dispatch(setProfileFormPhone(phoneNumber));
},
converter: (store) => store.state,
builder: (context, state) {
PhoneNumber? phoneNumber = state.profileForm?.phoneNumber ??
PhoneNumber(
phoneNumber: state.profile.phoneNumber,
isoCode: "GB",
);
return InternationalPhoneNumberInput(
onInputChanged: (PhoneNumber phone) {
final store = StoreProvider.of<AppState>(context);
store.dispatch(setProfileFormPhone(phone));
},
initialValue: PhoneNumber(
phoneNumber: phoneNumber.phoneNumber,
isoCode: phoneNumber.isoCode ?? "GB",
),
inputBorder: const OutlineInputBorder(),
selectorConfig: const SelectorConfig(
setSelectorButtonAsPrefixIcon: true,
leadingPadding: 8,
selectorType: PhoneInputSelectorType.BOTTOM_SHEET,
useEmoji: true,
),
);
},
),
);
}
}
I run into the same problem.
An easier fix i found was to initialise the PhoneNumber()
object in the initState
method just once and then just reference it in your build method.
I guess the bug is somehow related by the fact that PhoneNumber()
gets reconstructed everytime the build methold is called. Since thats basically what setState
is doing.
I also found a solution.
The way I fixed that was creating a var outside the build method like
final initialCountryValue = PhoneNumber(isoCode: Platform.localeName.split('_').last);
After that you pass that as initial value
InternationalPhoneNumberInput( onInputChanged: onInputChanged, initialValue: initialCountryValue)
The same Issue here I solved this using 2 different vars
one of them for just setting the initial value and the other to keep tracking the changed value, but still this issue must be fixed