Bloc isn't found in the widget tree

Issue

Because the code is to big I will try and sum it up in words.

This is the latest exception:

Error: Could not find the correct Provider<ProdEntriesSearchCubit> above this BlocListener<ProdEntriesSearchCubit, ProdEntriesSearchState> Widget

This likely happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:

- The provider you are trying to read is in a different route.

  Providers are "scoped". So if you insert of provider inside a route, then
  other routes will not be able to access that provider.

- You used a `BuildContext` that is an ancestor of the provider you are trying to read.

  Make sure that BlocListener<ProdEntriesSearchCubit, ProdEntriesSearchState> is under your MultiProvider/Provider<ProdEntriesSearchCubit>.
  This usually happens when you are creating a provider and trying to read it immediately.

In screen 1 I have the following build method:

    Widget build(BuildContext context) {
        final entriesState = context.watch<ProdEntriesCubit>().state;
        return BlocProvider(
          create: (context) => ProdEntriesSearchCubit(
            productsRepository: context.watch<ProductsRepository>(),
          ),
          child: Builder(
            builder: (context) => SafeScreen(
              child: Scaffold(
                body: _buildBody(context, entriesState: entriesState),
                floatingActionButton: _buildFab(context),
              ),
            ),
          ),
        );
      }

_buildFab(BuildContext context) {
    return FloatingActionButton(
      child: Icon(
        Icons.add,
        color: Colors.white,
      ),
      onPressed: () async {
        await navigatorPush(context, screen: AdminProdEntryScreen());
      },
    );
  }

In AdminProdEntryScreen I do again:

navigatorPush(
          context,
          screen: EntryProdSearchScreen(),
        );

In EntryProdSearchScreen I get the error from above.

Why is the BloC/Cubit not found in the widget tree?

I even used multiple Builder widgets but I am always hit by this exception.

Solution

When you provide your BLoC, it has access to the current widget tree, when you navigate to another screen it won’t have access to that BLoC.
You can solve this in one of two ways.

1
You wrap your whole app with a bloc (Multi) provider that you can access the bloc no matter the navigation.
The reason that this works is because you are wrapping your navigation within MaterialApp with the bloc provider.

  runApp(
    MultiBlocProvider(
      providers: [
        BlocProvider<ProdEntriesSearchCubit>(
          create: (context) => ProdEntriesSearchCubit(),
        ),
      ],
      child: MyApp(),
    ),
  );

2
You can pass an instance of the bloc through the nav route and use BlocProvider.value to provide the same instance of the bloc.


//nav method
Navigator.of(context).pushNamed(
  '/entry_prod_search_screen',
  arguments: context.read< ProdEntriesSearchCubit >(),
);

//in the navigated route screen
final bloc = ModalRoute.of(context).settings.arguments;

return MultiBlocProvider(
  providers: [
    BlocProvider.value(
      value: bloc,
    ),
  ],
  child: ...,
);

Answered By – mrgnhnt96

Answer Checked By – Dawn Plyler (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.