简体   繁体   中英

I am having trouble getting last emitted state with BlocBuilder in other widgets/classes in flutter using Bloc/cubit

I have a sign in cubit, which will take two parameters, email and password. then it will ask repository to give him response of that request. Before calling the function of repository I emit loading state, and when I received data from repository another state is emitted which is SigninLoaded. My SigninCubit:

final SignInRepository signInRepository;

SigninCubit({required this.signInRepository}) : super(SigninInitial());

Future<void> signIn({String email = '', String password = ''}) async {
  print("Cubit is invoked");
  emit(SigninInLoading());
  Timer(Duration(seconds: 0), () async {
    await signInRepository
        .signIn(email: email, password: password)
        .then((signinModel) {
      // print("SignIn Model is : ${signinModel}");‹‹
      emit(SigninLoaded(signInModel: signinModel));
    });
  });
}
}

SigninState

@immutable
abstract class SigninState {}

class SigninInitial extends SigninState {}

class SigninInLoading extends SigninState {}

class SigninLoaded extends SigninState {
  SignInModel? signInModel;
  SigninLoaded({required this.signInModel});
}

This is how I invoked my signinCubit from LoginPage class.

BlocProvider.of<SigninCubit>(context).signIn(email: email, password: password);

When signinCubit is invoked from LoginPage class, I see it's response in the same class using BlocBuilder like this;

BlocBuilder<SigninCubit, SigninState>(
        builder: (context, state) {
          if ((state is SigninInitial)) {
            print("Initial State");
          } else if (state is SigninInLoading) {
            return Center(
              child: CircularProgressIndicator(
                color: AppColors.mainColor,
              ),
            );
          } else {
            final signinData = (state as SigninLoaded).signInModel;

            data = signinData;
          }

But when I try to access response or the last emitted state which was SigninLoaded, I get initial state in other class, I tried to get response in Profile class like this;

BlocBuilder<SigninCubit, SigninState>(
                builder: (context, state) {
                  print("State : $state");
                  if (state is SigninLoaded) {
                    name = (state as SigninLoaded).signInModel?.data?.firstName;
                    print("Name $name");
                  }
                  return Text(
                    'Welcome, ${name}!',
                    style: TextStyle(
                      color: Colors.black,
                      fontSize: 20,
                      fontWeight: FontWeight.w800,
                    ),
                  );
                },
              ),

And I get no response back, because it says it is in initial state.

Even though I have provided Blocs as well like so;

BlocProvider to LoginPage class;

MaterialPageRoute(
          builder: (_) => BlocProvider(
            create: (BuildContext context) =>
                SigninCubit(signInRepository: signInRepository),
            child: LoginPage(),
          ),
        );

BlocProvider to Profile class;

 MaterialPageRoute(
            builder: (_) => BlocProvider(
                  create: (context) =>
                      SigninCubit(signInRepository: signInRepository),
                  child: Profile(),
                ));

May be Im wrong, but in my oppinion, if you want to use the SignInModel in Profile page, you've to call signIn function Again

  • Another Solution: define just one BlocProvider of SignInCubit as parrent of both Profile page and SignIn page, for example:

    MaterialPageRoute( builder: (_) => BlocProvider( create: (context) => SigninCubit(signInRepository: signInRepository), child: MyApp(), ));

  • Save signinModel or (sign in information) in local database, and when we enter ProfilePage, get it from db

I'm having a similar issue. I have a temporary workaround in place that works for me where I wrap the emit in a Future.delayed, like so

Future.delayed(Duration.zero,()=>emit(<<newState>>));

then My BlocBuilder recognizes the state change. I have no idea why, the thing is, my code worked fine a one time, then stopped with a seemingly unrelated change. Hope this helps somehow, but more than that, I hope someone who actually knows what's happening can tell me what I should actually do to fix my code:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM