Search code examples
flutterdartbloccubit

how can i transfer bloc provider


i want to transfer my bloc provider to other page but how can i do that ?

I have a sign in page. If user can log in the app (with email and password) he goes to homePage. The program gives error, because sign in page has signInCubit, but homePage has not. How can i transfer this bloc builder ? I tried blocprovider.value but it can't.

it gives this error: Error: Could not find the correct Provider above this BlocListener<SignInCubit, SignInState> Widget

my sign in page:

class SignInPage extends StatelessWidget {
  static const String id = 'sign_in_page';
  SignInPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocProvider<SignInCubit>(
      create: (context) => SignInCubit(),
      child: BlocListener<AuthCubit, AuthState>(
        listenWhen: (AuthState previous, AuthState current) =>
            previous.isUserSignedIn != current.isUserSignedIn &&
            current.isUserSignedIn,
        listener: (context, state) {
         Navigator.of(context).push(MaterialPageRoute(
            builder: (_) => BlocProvider.value(value: BlocProvider.of<SignInCubit>(context),child: HomePage(),),
          ));
        },
        child: Scaffold(body: signInPageWidget(context)),
      ),
    );
  }
}

my home page:

class HomePage extends StatelessWidget {
  static const String id = 'home_page';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: MultiBlocListener(
          listeners: [
            BlocListener<AuthCubit, AuthState>(
                listenWhen: (p, c) =>
                    p.isUserSignedIn != c.isUserSignedIn && !c.isUserSignedIn,
                listener: (context, state) {
                  Navigator.of(context).push(MaterialPageRoute(
                    builder: (_) => SignInPage(),
                  ));
                }),
            BlocListener<SignInCubit, SignInState>(
                listenWhen: (p, c) =>
                    p.errorMessage != c.errorMessage && c.errorMessage != "",
                listener: (context, state) {
                  print(state.errorMessage);
                }),
          ],
          child: BlocBuilder<SignInCubit, SignInState>(
            builder: (context, SignInState state) {
              return Center(
                child: state.isInProgress
                    ? CircularProgressIndicator()
                    : homePageBody(state, context)
              );
            },
          ),
        ));
  }
}

Solution

  • BlocProvider automatically disposes of a bloc instance with context of new route instantiated, but that will not happen if you use BlocProvider.value:

    BlocProvider.value(
      value: BlocProvider.of<BlocA>(context),
      child: ScreenA(),
    );
    

    Important note: BlocProvider.value should only be used for providing existing instances to new subtree, do not create Bloc instance with it, also if you want your BlocProvider to be in scope of whole app, wrap the root of your app, MaterialApp, and that will do the trick. Also be sure to dispose of your bloc instance using PlocProvider.value, as it will not do it automatically.