Bloc: BlocProvider keep throwing errors even when everything fine

Created on 14 Nov 2020  路  6Comments  路  Source: felangel/bloc

Hey, I'm reporting this kind of issue.. I've been using flutter bloc for a long time but never faced this problem before.
I'm providing a Cubit by using the BlocProvider widget locally inside the onGenerateRoute method that belongs to the MaterialApp and this Cubit should wrap that route and its context, but still giving me that this context doesn't contain any cubit of that type!!
Tried globally wrapping the entire MaterialApp with MultiBlocProvider worked fine except with the route.
Note: I'm working on a big project so I sharing lots of different areas of code could be hard to read but I'll share the most important.

This is the app router:

class AppRoutes {
  static Route<dynamic> onGenerateRoutes(RouteSettings settings) {
    switch (settings.name) {
      case '/':
        return MaterialPageRoute(builder: (_) => MainView());
        break;

      case '/ProductsView':
        return MaterialPageRoute(
          builder: (_) => MultiBlocProvider(providers: [
            BlocProvider<ProductsCubit>(create: (_) => ProductsCubit()),
            // others...
          ], child: ProductsView(args: settings.arguments)),
        );
        break;

      case '/ProductInfoView':
        return MaterialPageRoute(
          builder: (_) => MultiBlocProvider(providers: [
            BlocProvider<ProductInfoCubit>(create: (_) => ProductInfoCubit()..fetchProductInfo(settings.arguments)),
            BlocProvider<QuantityCounterCubit>(create: (_) => QuantityCounterCubit()),
            BlocProvider<CategoriesCubit>(create: (_) => CategoriesCubit()..fetchCategories()),
            // others
          ], child: ProductInfoView(id: settings.arguments)),
        );
        break;

      case '/FilterView':
        return MaterialPageRoute(builder: (_) => FilterView(args: settings.arguments));
        break;

      case '/BrandsView':
        return MaterialPageRoute(builder: (_) => BrandsView());
        break;

      case '/StoresView':
        return MaterialPageRoute(builder: (_) => StoresView());
        break;

      case '/CategoriesView':
        return MaterialPageRoute(builder: (_) => CategoriesView());
        break;

      case '/ColorsView':
        return MaterialPageRoute(builder: (_) => ColorsView());
        break;

      case '/SizesView':
        return MaterialPageRoute(builder: (_) => SizesView());
        break;

      case '/CartPageView':
        return MaterialPageRoute(builder: (_) => CartPage(showPageAsView: true));
        break;

      case '/LanguageView':
        return MaterialPageRoute(builder: (_) => LanguageView(isFromSettings: settings.arguments));
        break;

      default:
        return null;
    }
  }

  static Route<dynamic> onUnknownRoute(RouteSettings settings) {
    return null;
  }
}

The cubit I'm having problems with is 'ProductsCubit'

And I'm calling a method inside the initState belongs to ProductsView and it throws this error
calling:

  @override
  void initState() {
    super.initState();
    if (_body != null) {
      BlocProvider.of<ProductsCubit>(context).withBodyRequest(body: _body);
      BlocProvider.of<ProductsCubit>(context).fetchProducts(isInitialLoad: true);
    }
  }

error:

E/flutter ( 9341): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception:         BlocProvider.of() called with a context that does not contain a Bloc/Cubit of type ProductsCubit.
E/flutter ( 9341):         No ancestor could be found starting from the context that was passed to BlocProvider.of<ProductsCubit>().
E/flutter ( 9341):
E/flutter ( 9341):         This can happen if the context you used comes from a widget above the BlocProvider.
E/flutter ( 9341):
E/flutter ( 9341):         The context used was: ProductsView(dependencies: [_InheritedTheme, _LocalizationsScope-[GlobalKey#a71c9]], state: _ProductsViewState#459b5)

Also this is a list of BlocPoviders that I'm passing to the MultiBlocProvider globally in the MaterialApp

class BlocProviders {
  static final List<BlocProvider> providers = [
    // App
    BlocProvider<AppLocaleCubit>(create: (_) => AppLocaleCubit()..initAppLocale()),
    BlocProvider<TopStatusBarCubit>(create: (_) => TopStatusBarCubit()),

    // Layout
    BlocProvider<LayoutCubit>(create: (_) => LayoutCubit()..fetchLayout()),

    // Categories
    BlocProvider<CategoriesCubit>(create: (_) => CategoriesCubit()..fetchCategories()),
    BlocProvider<SubCategoriesCubit>(create: (_) => SubCategoriesCubit()),

    // Products
    // BlocProvider<ProductsCubit>(create: (_) => ProductsCubit()), // Working HERE!!
    BlocProvider<FavoriteProductsCubit>(create: (_) => FavoriteProductsCubit()..initFavoriteProducts()),

    // Search History
    BlocProvider<SearchHistoryCubit>(create: (_) => SearchHistoryCubit()..initSearchHistory()),

    // Brands
    BlocProvider<BrandsCubit>(create: (_) => BrandsCubit()..fetchBrands(isInitialLoad: true)),

    // Stores
    BlocProvider<StoresCubit>(create: (_) => StoresCubit()..fetchStores(isInitialLoad: true)),

    // Filter
    BlocProvider<FilterCubit>(create: (_) => FilterCubit()),
  ];
}

Finally, the main

class MainApp extends StatelessWidget {
  const MainApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: BlocProviders.providers,
      child: BlocBuilder<AppLocaleCubit, AppLocaleState>(
        buildWhen: (previous, current) => previous.locale.languageCode != current.locale.languageCode,
        builder: (_, localeState) => MaterialApp(
          debugShowCheckedModeBanner: false,
          // app localization
          locale: localeState.locale,
          supportedLocales: AppLocalizationsSetup.supportedLocales,
          localizationsDelegates: AppLocalizationsSetup.localizationsDelegates,
          localeResolutionCallback: AppLocalizationsSetup.localeResolutionCallback,
          title: MATERIAL_APP_TITLE,
          // app themes
          theme: AppThemes.lightTheme,
          // app routes
          onGenerateRoute: AppRoutes.onGenerateRoutes,
          onUnknownRoute: AppRoutes.onUnknownRoute,
        ),
      ),
    );
  }
}

The cubit itself is working fine since I tried it globally.. and other blocs/cubits are just fine too, but to be honest I have no idea why I'm even stuck here.
ANY SOLUTIONS?

question

Most helpful comment

Hi @narcodico I'm going to close this issue since I ran some tests yesterday and found the error was from the imports statement that causes this issue.
Thanks for helping out.

All 6 comments

Hi @abdulmuaz97 馃憢

Are you accessing your ProductsCubit within a dialog or something like that inside your ProductsView ?

@narcodico No, I'm calling a method that belongs to that Cubit inside the initState of ProductsView and it throws the error explained above.

Please share a sample app reproducing your issue and I'll have a look! 馃憖

Well, it's a big project.. Can't share the whole code here!

That's precisely why I asked for a sample app(a minimal app reproducing your issue)! 馃槈

Hi @narcodico I'm going to close this issue since I ran some tests yesterday and found the error was from the imports statement that causes this issue.
Thanks for helping out.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

clicksocial picture clicksocial  路  3Comments

wheel1992 picture wheel1992  路  3Comments

craiglabenz picture craiglabenz  路  3Comments

timtraversy picture timtraversy  路  3Comments

shawnchan2014 picture shawnchan2014  路  3Comments