bloc icon indicating copy to clipboard operation
bloc copied to clipboard

onGenerateRoute pushNamed creates sibling and cannot access BlocProvider from screen that calls pushNamed

Open mateoKutnjak opened this issue 2 years ago • 3 comments

Hi. Can you add to documentation or explain how to perform routing of two screens (parent and child) where parent is wrapped inside BlocProvider<XYZBloc> and when inside its build method parent calls Navigator.of(context).pushNamed('child') and then child calls context.read<XYZBloc>()... it does not throw BlocProviderNotFoundException because onGenerateRoute creates child as sibling of parent and they do not share same context?

I think many other face the same problem.

Thank you.

mateoKutnjak avatar Jun 04 '22 16:06 mateoKutnjak

I believe I've figured out a solution to the problem you're having. You'll have to add the AutoRoute package to your code though, along with the AutoRouteGenerator and BuildRunner package. I don't know if you've used auto-route before, but it's probably the best routing package available for Flutter projects.

In the link below, I've uploaded a small Flutter project demonstrating how to call the cubit of a parent route. Basically what I did was create a Home router, with the Home page as the default page that it routes to. Then I also put a RandomPage page in the Home router.

The Home router contains a BlocProvider for the Home page that's available to any of its children (such as RandomPage). The Home router is simply the home_wrapper.dart file. The Home wrapper/router is an empty widget with a BlocProvider and an AutoRoute child that automatically routes to the Home widget, since the path of the Home widget's route is an empty string (look at the path in the router.dart file).

This routing system, which leverages Auto-Route's nested routing functionality, is how I access the Bloc/Cubit of a parent from the child widget.

The program's home page has a button that navigates to the RandomPage. The RandomPage has a button that calls on a function inside the Home cubit. The function simply changes the Home cubit's state to HomeLoading(), which just returns a CircularProgressIndicator.

If this is what you were looking to do, then let me know so I can add it to the documentation. If not, please tell me the problem, and I can modify the code to solve that problem.

https://github.com/ryandoak/bloc_routing

ryandoak avatar Jun 05 '22 01:06 ryandoak

I like the idea of using auto_route package. Wouldn't you rather use AutoRouteWrapper to avoid creating HomeWrapper widget? So in your example Home widget would implement AutoRouteWrapper and implement method

@override
Widget wrappedRoute(BuildContext context) {
   => MultiBlocProvider(
    providers: [
      BlocProvider<HomeCubit>(
        create: (context) => HomeCubit(),
      ),
    ],
    child: this, // before it was const AutoRouter(), so where to put that?
  );
}

I think that would require less code and .dart files (HomeWrapper)

mateoKutnjak avatar Jun 05 '22 08:06 mateoKutnjak

Hi @ryandoak, whether have example for use cubit with go_router package? .. i through same issue with above problem. i cannot access cubit from parent screen route.

Thanks

yunus-floo avatar Jul 01 '22 01:07 yunus-floo