I am still learning how to use cubits and blocs, and I am trying to use a cubit in my project, but I got a little bit confused about how to use it.
There is a screen that requires a phone number and I use the lib "intl_phone_number_input" to format, validate and select the country. When I click the button to the next page it needs to check if the phone is valid, but I need to have a variable that stores this info. The widget InternationalPhoneNumberInput has a property onInputValidated that returns true if the phone number is valid, so where should I create this variable? Should I create it in my widget class or inside the cubit? I created it inside cubit but I am not sure if it is the correct way, so I got this:
onInputValidated: (bool value) {
BlocProvider.of<LoginCubit>(context).isValid =
value;
},
I've studied and seen some examples about cubits and how to use'em but I still didn't get it at all, because in the examples the cubit never used a variable, all variables became a state, but in my case, I need the value as a variable.
I am confused too about how to show a dialog using cubit, I've done it this way:
@override
Widget build(BuildContext context) {
return BlocConsumer<LoginCubit, LoginState>(
listenWhen: (previous, current) => current is ShowDialogErrorLoginState || current is NavigateFromLoginStateToHomePageState,
listener: (context, state) {
if (state is ShowDialogErrorLoginState) {
showErrorDialog(context, state.titleMessage, state.bodyMessage);
}
if (state is NavigateFromLoginStateToHomePageState) {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => const MyHomePage()));
}
},
builder: (context, state) {
if (state is ShowLoginState) {
return buildPhoneForm(context);
}
if (state is SendingCodeLoginState) {
return ProgressView(message: 'Sending SMS code',);
}
if (state is ShowCodeLoginState) {
return buildCodeForm(context);
}
return const ErrorView('Unknown error');
},
);
}
and in my cubit I did the following:
void goToCodeVerification(String phoneNumber) async {
if (!isValid){
String titleMessage = "Phone number invalid";
String bodyMessage = "The given phone number is invalid";
emit(ShowDialogErrorLoginState(titleMessage, bodyMessage));
emit(ShowLoginState());
} else {
emit(SendingCodeLoginState());
// TO DO
// use API to send a code
emit(ShowCodeLoginState());
}
}
Is this the correct way to show a dialog with a cubit?
Ok, so you have a value you want to use, the variable doesn't affect state, and you need to access it inside your cubit.
for something like this, I think storing the variable on the cubit makes the most sense, but keep in mind either approach is acceptable for such a simple case.
I also don't really like how the below code looks:
onInputValidated: (bool value) {
BlocProvider.of<LoginCubit>(context).isValid =
value;
},
it is a bit clunky, I would prefer to move the whole callback into the cubit:
void onInputValidated(bool value) => isValid = value;
that way:
final cubit = BlocProvider.of<LoginCubit>(context);
...
onInputValidated: cubit.onInputValidated,