felangel / bloc

A predictable state management library that helps implement the BLoC design pattern
https://bloclibrary.dev
MIT License
11.79k stars 3.39k forks source link

Login tutorial with BlocListener #221

Closed furkanvatandas closed 5 years ago

furkanvatandas commented 5 years ago

I tried to BlocListener with your Login tutorial example. When I press Login button, it's open HomeScreen() but it prints "AppState AuthenticationAuthenticated" twice in BlocBuilder. Is it normal?

BlocListener(
          bloc: authenticationBloc,
          listener: (BuildContext context, AuthenticationState state) {
            if (state is AuthenticationAuthenticated) {
              print("AppState AuthenticationAuthenticated Listener");
              Navigator.push(context, MaterialPageRoute(builder: (context) => HomeScreen()));
            }
          },
          child: BlocBuilder<AuthenticationEvent, AuthenticationState>(
            bloc: authenticationBloc,
            builder: (BuildContext context, AuthenticationState state) {
              if (state is AuthenticationUninitialized) {
                return SplashScreen();
              }
              if (state is AuthenticationAuthenticated) {
                print("AppState AuthenticationAuthenticated");
                return Container(color: Colors.red);
              }
              if (state is AuthenticationUnauthenticated) {
                print("AppState AuthenticationUnauthenticated");
                return LoginScreen(userRepository: userRepository);
              }
              if (state is AuthenticationLoading) {
                print("AppState AuthenticationLoading");
                return LoadingIndicator();
              }
            },
          ),
        ),
felangel commented 5 years ago

Hi @furkanvatandas 👋 Thanks for opening an issue!

That’s strange...are you sure it’s not one print from BlocListener and one from BlocBuilder? I see you have two print statements in your example and what should happen is BlocListener should be called with Authenticated and then BlocBuilder should be called with Authenticated after. Let me know if you remove the print from BlocListener does it still print twice?

Thanks! 👍

furkanvatandas commented 5 years ago

That’s strange...are you sure it’s not one print from BlocListener and one from BlocBuilder? Yes, I am sure that it is same print.

When delete BlocListener, it works fine only one print. But with BlocListener it's opening HomeScreen and then print "AppState AuthenticationAuthenticated" twice.

Console: -- AppState AuthenticationAuthenticated Listener -- AppState AuthenticationAuthenticated -- AppState AuthenticationAuthenticated

felangel commented 5 years ago

Thanks I’ll take a look shortly 👍

felangel commented 5 years ago

@furkanvatandas I took I look and was able to reproduce the behavior you're describing. The builder method can be invoked many times by Flutter and it's totally normal.

The build method is designed in such a way that it should be pure/without side effects. This is because many external factors can trigger a new widget build, such as:

sohitEngg commented 5 years ago

Is there a way to test Widget for the BlocListener. I want to test if a state gets changed and captured in BlocListener.

felangel commented 5 years ago

@sohitEngg have you taken a look at https://github.com/felangel/bloc/issues/361?