I am trying to integrate flutter_login widget with bloc. Here is the sample code I am using
BlocProvider(
create: (ctx) => UserAuthenticationPageBloc(ctx),
child: BlocListener<UserAuthenticationPageBloc, UserAuthenticationPageState>(
listener: (context, state) {
// not used at the moment
},
child: BlocBuilder<UserAuthenticationPageBloc, UserAuthenticationPageState>(
builder: (context, state) {
final bloc = context.read<UserAuthenticationPageBloc>();
return FlutterLogin(onLogin: (loginData) async {
bloc.add(SignIn(loginData: loginData));
return state.loginMessage;
}, onRecoverPassword: (email) async {
bloc.add(RecoverPassword(email: email));
return state.recoverPasswordMessage;
});
},
),
),
)
Here is the bloc file
class UserAuthenticationPageBloc extends Bloc<UserAuthenticationPageEvent, UserAuthenticationPageState> {
UserAuthenticationPageBloc(BuildContext context) : super(const UserAuthenticationPageState()) {
on<SignIn>((event, emit) {
try {
emit(state.copyWith(signInStatus: SignInStatus.loading));
User user = User(); // need to be replaced by async http call
final GlobalBloc globalBloc = BlocProvider.of<GlobalBloc>(context);
globalBloc.add(GlobalSignIn(user: user));
emit(state.copyWith(loginMessage: 'some error', signInStatus: SignInStatus.failure));
} catch (_) {
//emit(CovidError("Failed to fetch data. is your device online?"));
}
});
on<RecoverPassword>((event, emit) {
});
}
}
What I would like to do is to add an event to bloc and then return a message. The flutter_login
widget will show snack bar based on the message returned.
How can I wait for bloc event to finish before retrieving the loginMessage from the state? Or maybe I should not put the loginMessage in state?
Thank you
2
Answers
You could try to pass
onLogin
function andonRecoverPassword
function and state in separate parameters, and insideFlutterLogin
checkonloginMessage
andrecoverPasswordMessage
not being null.I also think you should you make yourself familiar with bloc by looking at different examples, I suggest the examples folder in the package itself https://github.com/felangel/bloc/tree/master/examples
In most scenarios, these types of things can all be handled pretty easily with the
BlocListener
widget. Usually, in the UI you don’t have to manuallyawait
anything coming from a bloc stream. This is one exception, where you’re trying to utilize the built in UI elements offlutter_widget
.Since the
onLogin
callback requires a return ofnull
on success or error message string on failure, you want toawait
the stream directly.The syntax for that looks like this
The whole widget would look something like this.
A couple things with what you shared.
BlocBuilder
widgets should not be placed directly below theBlocProvider
. So in this case, to avoid that you could just create a new widget with theBlocBuilder
wrapping aFlutterLogin
. Although as you can see, in this case to use the built in snackbar, you don’t need theBlocBuilder
here.UserAuthenticationPageBloc
depends directly onGlobalBloc
, which according to the docs should be avoided at all times. This is easily avoided with theBlocListener
widget. I’m also not seeing why there are 2 separate blocs here at all just for login. So my example was simplified to just one Bloc class that handles login.The gif below shows a 2 second wait and the bloc emitting an error state.