RivaanRanawat/blog-app-clean-architecture

BuildSelector doesn't rebuild when state AppUserCubit emit new state changes

Closed this issue · 0 comments

I encountered an issue where the isLoggedIn variable in the BlocSelector is always false despite the AppUserCubit transitioning to AppUserLoggedIn state. This results in the UI displaying the SignupPage instead of the expected Logged in User Page.

Steps i have done :
Re Launch the application.
Verified that the AuthIsUserLoggedIn event is dispatched and processed correctly.
Check the BlocSelector output and the UI display.
Expected Behavior :
The isLoggedIn variable in the BlocSelector should correctly reflect the user's login status, displaying the appropriate UI message (User Logged in or SignupPage).

here is the debbug console :

I/flutter (24114): isLoggedIn in builder: false
I/flutter (24114): AuthIsUserLoggedIn success: hoda@gg.com
I/flutter (24114): isLoggedIn in builder: true

DI :

final serviceLocator = GetIt.instance;

Future<void> initDependencies() async {
//core
  serviceLocator.registerLazySingleton(() => AppUserCubit());

  _initAuthDependncy();

  final url = dotenv.env['SUPA_BASE_URL'];
  final anonKey = dotenv.env['anon_key'];

  final supabase = await Supabase.initialize(
    url: url!,
    anonKey: anonKey!,
  );

  serviceLocator.registerLazySingleton(() => supabase.client);
}

void _initAuthDependncy() {
  serviceLocator
    //auth data surce
    ..registerFactory<AuthRemoteDataSource>(
        () => AuthRemoteDataSourceImpl(serviceLocator()))

//repository
    ..registerFactory<AuthRepository>(
        () => AuthRepositoryImpl(serviceLocator()))
    //user auth use case.
    ..registerFactory(() => UserSignUpuseCase(serviceLocator()))
    ..registerFactory(() => UserLogInuseCase(serviceLocator()))
    ..registerFactory(() => GetCurrentUserUseCase(serviceLocator()))
    ..registerLazySingleton(
      () => AuthBloc(
        userSignUp: serviceLocator(),
        userLogin: serviceLocator(),
        currentUser: serviceLocator(),
        appUserCubit: serviceLocator(),
      ),
    );
}

AppUserCunit :

class AppUserCubit extends Cubit<AppUserState> {
  AppUserCubit() : super(AppUserInitial());

  void updateUser(User? user) {
    if (user == null) {
      emit(AppUserInitial());
    } else {
      emit(AppUserLoggedIn(user));
    }

    @override
    void onChange(Change<AppUserState> change) {
      print(
          'here is the on change app user cubit, current :  ${change.currentState}, next state : ${change.nextState}');
      super.onChange(change);
    }
  }
}

BlocSelector :

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Blog App',
      theme: AppTheme.darkThemeMode,
      home: BlocSelector<AppUserCubit, AppUserState, bool>(
        selector: (state) {
          return state is AppUserLoggedIn;
        },
        builder: (context, isLoggedIn) {
          print('isLoggedIn in builder: $isLoggedIn');

          if (isLoggedIn) {
            return const Scaffold(
              body: Center(
                child: Text('User Logged in'),
              ),
            );
          } 
            return const SignupPage();
        },
      ),
    );
  }

In the data layer everything works as expected, the AppUserCubit emits the sate successfully but i think it doesn't trigger a rebuild,
what am i doing wrong?