TechieBlossom / movie_app_tutorial

MIT License
238 stars 80 forks source link

How to get the same instance of a Cubit in multiple screens using BlocProvider with get_it? #35

Open apptechxonia opened 1 year ago

apptechxonia commented 1 year ago

I have two screens, Screen A and Screen B. To redirect from Screen A to Screen B, I used the go_router implementation. I initialized the bloc in Screen A as shown below:

MultiBlocProvider(
  providers: [
    BlocProvider(create: (context) => getIt<ScreenOneCubit>()),
    BlocProvider(create: (context) => getIt<GenericFormFieldCubit<FormzInput>>()),
  ],
  child: ScreenA(),
);


For Screen B: 
 
``` 
BlocProvider.value( value: getIt(), child: ScreenB(), );


In Di.dart, I registered the ScreenOneCubit using



getIt.registerFactory( () => ScreenOneCubit()
);



To redirect from Screen A to Screen B, I used GoRouter.of(context).pushNamed("screenB”).
I assumed that the BlocProvider.value in Screen B would get the same cubit instance as Screen A, but I was not expecting the same instance.
How can I get the same instance as Screen A in Screen B?

@PrateekSharma1712  @TechieBlossom   Could you provide some ideas?
TechieBlossom commented 1 year ago

Because it is registered as a factory, so whenever you write getIt<ScreenOneCubit>(), it will return with a new instance. You can also not use context.read<ScreenOneCubit>(), because context is changed which navigating.

You can declare this cubit as singleton/lazySingleton. If you don't wanna do this, maybe re-thinking the idea of why you need same bloc in two screens should be considered. I can guide you on that, if I know more of real situation. Hope, my answer is useful.

BTW, in my latest series, I have also rectified a mistake related to bloc to bloc communication that I made in MovieApp series. You can check that here - https://www.youtube.com/playlist?list=PL342JVRNQxEC3g0b1GsWwUctUsx5H7txz

apptechxonia commented 1 year ago

@TechieBlossom

Requirement: To ensure a seamless flow, I have a module consisting of 7 screens. Upon clicking a button on the first screen, I make an API call and receive a response that is necessary for screens 4 and 7. To utilize the data, I pass it through each screen. To simplify the process, I wish to use a single Cubit instance to handle this data and easily access it on the relevant page. Can you suggest any approaches to accomplish this?

Initially, I tried using a singleton-lazy instead of registerFactory to get the Cubit instance. However, after pressing the "Back" button and returning to screen 1, I called the API using the "Next" button, and although the API was called successfully, the BlocListener I was using to listen to the state was no longer triggered. To make the BlocListener listener again on screen 1, I had to close the application. Therefore, I returned to using the registerFactory method.

teewhydope commented 3 months ago

@TechieBlossom

Requirement: To ensure a seamless flow, I have a module consisting of 7 screens. Upon clicking a button on the first screen, I make an API call and receive a response that is necessary for screens 4 and 7. To utilize the data, I pass it through each screen. To simplify the process, I wish to use a single Cubit instance to handle this data and easily access it on the relevant page. Can you suggest any approaches to accomplish this?

Initially, I tried using a singleton-lazy instead of registerFactory to get the Cubit instance. However, after pressing the "Back" button and returning to screen 1, I called the API using the "Next" button, and although the API was called successfully, the BlocListener I was using to listen to the state was no longer triggered. To make the BlocListener listener again on screen 1, I had to close the application. Therefore, I returned to using the registerFactory method.

Either use listenwhen to prevent unecessary update of your bloc state or use BlocProvider.create, then pass it to the next screen as an argument. Blocprovider.value is not suitable in most cases