Flutter
Summary - Bloc advanced
Combine Bloc, event and state to make a login flow.
Login flow
In a login flow, Bloc, event and state work together. When the user presses the button, LoginSubmittedEvent is triggered; the Bloc receives it, first emits LoginLoading, then on completion transitions to LoginSuccess or LoginFailure. The UI uses BlocBuilder to show different widgets for each state.
class LoginBloc extends Bloc<LoginEvent, LoginState> {
LoginBloc() : super(LoginInitial()) {
on<LoginSubmittedEvent>((event, emit) async {
emit(LoginLoading());
await Future.delayed(Duration(seconds: 1));
emit(LoginSuccess('Ayşe'));
});
}
}
Exercise Write a complete login Bloc
Define LoginEvent and LoginSubmittedEvent. Write the LoginState abstract class with LoginInitial, LoginLoading, and LoginSuccess (holds a username) subclasses. LoginBloc should start with LoginInitial; its LoginSubmittedEvent handler should first emit LoginLoading, then after a short delay emit LoginSuccess('Ayşe'). In main, trigger the event, wait, and print the username on success.
Show example solution
import 'package:bloc/bloc.dart';
abstract class LoginEvent {}
class LoginSubmittedEvent extends LoginEvent {}
abstract class LoginState {}
class LoginInitial extends LoginState {}
class LoginLoading extends LoginState {}
class LoginSuccess extends LoginState {
final String user;
LoginSuccess(this.user);
}
class LoginBloc extends Bloc<LoginEvent, LoginState> {
LoginBloc() : super(LoginInitial()) {
on<LoginSubmittedEvent>((event, emit) async {
emit(LoginLoading());
await Future.delayed(Duration(milliseconds: 10));
emit(LoginSuccess('Ayşe'));
});
}
}
void main() async {
final bloc = LoginBloc();
bloc.add(LoginSubmittedEvent());
await Future.delayed(Duration(milliseconds: 50));
final state = bloc.state;
if (state is LoginSuccess) {
print(state.user);
}
}
Test yourself
-
What happens when the button is pressed in a login flow?
- The state becomes LoginSuccess immediately
- LoginSubmittedEvent is triggered and the Bloc processes it
- BlocBuilder does not rebuild
- The event class is removed from memory
Show answer
LoginSubmittedEvent is triggered and the Bloc processes it — When the button is pressed, a LoginSubmittedEvent is created and sent to the Bloc via bloc.add; the Bloc processes the event and produces state.
-
Emit loading state
on<LoginSubmittedEvent>((event, emit) async {
____(LoginLoading());
await Future.delayed(Duration(milliseconds: 10));
emit(LoginSuccess('Ayşe'));
});
Show answer
on<LoginSubmittedEvent>((event, emit) async {
emit(LoginLoading());
await Future.delayed(Duration(milliseconds: 10));
emit(LoginSuccess('Ayşe'));
});
-
Login flow parts
- LoginSubmittedEvent
- User intent
- LoginLoading
- Waiting state
- LoginSuccess
- Success state
- on<LoginSubmittedEvent>
- Event handler
Next lesson: What is Hive?