Dart: How to properly dispatch bloc event in another bloc


I need to access AuthenticationBloc in my LoginBloc so I can fire the AuthenticationLogin() event if the login is successful. What I did so far is not working.

What I’ve done:

class LoginBloc extends Bloc<LoginEvent, LoginState> {
  final AuthenticationBloc authenticationBloc;
  final AuthenticateCredentialsUsecase authenticateCredentialsUsecase;


  Stream<LoginState> mapEventToState(
    LoginEvent event,
  ) async* {
        yield LoginLoadSuccess();

What I’m trying to accomplish:

class _AppViewState extends State<AppView> {

  final _navigatorKey = GlobalKey<NavigatorState>();
  NavigatorState get _navigator => _navigatorKey.currentState;

  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: _navigatorKey,
      builder: (context, child) {
        return BlocListener<AuthenticationBloc, AuthenticationState>(
          listener: (context, state) {
             if (state is AuthenticationAuthenticated) {
                  (route) => false,
             else if (state is AuthenticationUnauthenticated){
                  (route) => false,
          child: child,
      onGenerateRoute: (_) => SplashPage.route(),

As you can see, the user is currently in the LoginScreen, once the login is successful, I need to yield the AuthenticationAuthenticated() state in my AuthenticationBloc() so my users will be directed to the HomePage()

How can I yield the AuthenticationAuthenticated() state of the AuthenticationBloc() inside my LoginBloc() – since my login logic happens inside the LoginBloc.


  1. I subscribed the AuthenticationBloc to the status stream of my AuthenticateCredentialsUsecase class.
  2. When the AuthenticateCredentialsUsecase is called in my LoginBloc and the credentials are authenticated…
  3. I then update the status stream – _controller.add(AuthenticationStatus.authenticated);
  4. Which inturn will trigger the AuthenticationLogin event
    inside the AuthenticationBloc


    @required CheckAuthenticationStatusUsecase checkAuthenticationStatus,
    @required LogoutAuthenticatedUserUsecase logoutAuthenticatedUser,
    @required AuthenticateCredentialsUsecase authenticateCredentials,
  })  : assert(checkAuthenticationStatus != null),
        assert(logoutAuthenticatedUser != null),
        assert(authenticateCredentials != null),
        checkAuthenticationStatusUsecase = checkAuthenticationStatus,
        logoutAuthenticatedUserUsecase = logoutAuthenticatedUser,
        authenticateCredentialsUsecase = authenticateCredentials,
        super(AuthenticationInitial()) {
    _loginStatusSubscription =
        authenticateCredentialsUsecase.status.listen((event) {
      if (event == AuthenticationStatus.authenticated) {


  final _controller = StreamController<AuthenticationStatus>();

  Stream<AuthenticationStatus> get status async* {
    yield AuthenticationStatus.unknown;
    yield* _controller.stream;

  void dispose() => _controller.close();

  Future<Either<Failure, AuthenticatedUser>> call(AuthenticationParams params) async {

    final result = await repository.authenticateCredentials(params.userName, params.password);

    if(result is Right){

    return result;

Answered By – Paula Ysabelle Medina

Answer Checked By – Jay B. (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *