Home > Net >  Error: Could not find the correct Provider<TimerState> above this Practice4HomePage Widget Flu
Error: Could not find the correct Provider<TimerState> above this Practice4HomePage Widget Flu

Time:02-23

I got an error when learning bloc in flutter

Error is Error: Could not find the correct Provider above this Practice4HomePage Widget

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

  • You added a new provider in your main.dart and performed a hot-reload. To fix, perform a hot-restart.

  • 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 Practice4HomePage is under your MultiProvider/Provider. This usually happens when you are creating a provider and trying to read it immediately.

    For example, instead of:

    Widget build(BuildContext context) {
      return Provider<Example>(
        create: (_) => Example(),
        // Will throw a ProviderNotFoundError, because `context` is associated
        // to the widget that is the parent of `Provider<Example>`
       child: Text(context.watch<Example>()),
      ),
    }
    

    consider using builder like so:

    Widget build(BuildContext context) {
      return Provider<Example>(
        create: (_) => Example(),
        // we use `builder` to obtain a new `BuildContext` that has access to the provider
        builder: (context) {
          // No longer throws
          return Text(context.watch<Example>()),
        }
      ),
    }
    

CodePudding user response:

You have to provide the bloc to your Practice4HomePage class. One way is to provide the bloc to entire widget tree i.e. wrapping MaterialApp with BlocProvider or MultiBlocProvider. Another way is to wrap BlocProvider where you are calling Practice4HomePage. So let's suppose you are navigating from ABC page to Practice4HomePage, you can wrap BlocProvider inside your navigation statement.

Example:

 Navigator.of(context).push(
                          MaterialPageRoute<HomeForm>(
                            builder: (context) => BlocProvider<TimerState>(
                              create: (context) => TimerState(),
                              child: Practice4HomePage(),
                            ),
                          ),
                        ),
                      ),

CodePudding user response:

Firstly, you need to use BlocProvider instead of Provider, and secondly, wrap your child widget with Builder because BlocProvider.of(context) (or in this case context.watch()) looks from current context up the tree to find your BlocProvider, and you use same context that you provided your Bloc with, so it can't find it up the tree because it's on the same level (same context), so just use suggestion that was provided by your error, or like this:

Widget build(BuildContext context) {
  return BlocProvider<Example>(
    create: (_) => Example(),
    child: Builder(builder: (context) => Text(context.watch<Example>())),
  ),
}

Or you can extract Text widget into a new StatelessWidget and that will also work because it will have it's own (new) BuildContext, like so:

class ParentWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider<Example>(
      create: (_) => Example(),
      child: ChildWidget(),
    ),
  }
}

class ChildWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(context.watch<Example>());
  }
}
  • Related