I try to trigger a simple action from a different class, using provider package. What I did:

1) I created a ChangeNotifier class named MySchedule which has a getter and a setter:

class MySchedule extends ChangeNotifier {
   bool _foodSet = false;
   bool get foodSet => _foodSet;
   set foodSet(bool newBool) {
    _foodSet = newBool;
    notifyListeners();
   }
}

The widget tree of this widget is the following (I made it shorter, than the original) - this is inside a stateful widget class

  @override
  Widget build(BuildContext context) {

    return  ChangeNotifierProvider(
        builder: (context) => MySchedule(),
    child: Scaffold(
        body: Stack(
      children: <Widget>[
        Container(
          child: AnotherWidgetWhichHasLotOfChild()
          ),
        ),
        AnimatedContainer(
          curve: Curves.fastOutSlowIn,
          duration: Duration(milliseconds: 500),
          alignment: Alignment(left, -1),
          child: MenuSheet(close: toggleMainMenu, change: changeToTab),
        ),
        FoodDetailsClass()
      ],
        ),
      ));
  }

The FoodDetailsClass has a container in a visibility, which 'visible' boolean I want to change with the provider:

class FoodDetailsClass extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return Consumer<MySchedule>(
        builder: (context, provider, child) => Visibility(
      visible: provider.foodSet,
      child: Center(
        child: Container(
          height: 600,
          width: 400,
          color: Colors.red,
        ),
      ),
    ));
  }
}

I want to change it from inside the "AnotherWidgetWhichHasLotOfChild()" class in this way: Inside the above mentioned class there is a following call (but it throws an error):

GestureDetector(
      onTap: (){
        final schedule2 =
        Provider.of<MySchedule>(context);
        schedule2.foodSet = true;
      }

The error is: Error: Could not find the correct Provider above this FoodList Widget

To fix, please:

  • Ensure the Provider is an ancestor to this FoodList Widget


Solution 1: Naslausky

Your call makes reference to a provider of MySchedule type:

Provider.of<MySchedule>(context)

As stated in the documentation:

This method will look up in the widget tree starting from the widget associated with the BuildContext passed and it will return the nearest variable of type T found (or throw if nothing is found).

Which will look up in the widget tree, looking for a provider with the closest type. Since it cannot find, it throws an error that tells you exactly that:

Could not find the correct Provider above this FoodList Widget

Try to replace your ChangeNotifierProvider declaration to contain the class it should provide:

@override
  Widget build(BuildContext context) {

    return  ChangeNotifierProvider<MySchedule>(
        builder: (context) => MySchedule(),
    child:
    [...]


Solution 2: rstrelba

Try to change declaration of MySchedule

class MySchedule with ChangeNotifier { ...