'Flutter provider error 'Could not find the correct Provider'

I'm getting the error:

The following ProviderNotFoundException was thrown building Widget1(dirty):
Error: Could not find the correct Provider<MyUser> above this FeedView 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 FeedView is under your MultiProvider/Provider<MyUser>.
  This usually happens when you are creating a provider and trying to read it immediately.

while using provider in my flutter app.

I looked at answers to this question on stackoverflow but couldn't find anything wrt what I'm doing wrong in my specific case.

My Code:

imports...

class FirstPage extends StatefulWidget {
  FirstPage({required this.user});

  final MyUser user;

  @override
  _FirstPageState createState() => _FirstPageState();
}

class _FirstPageState extends State<FirstPage> {
  int selectedIndex = 0;
  final List<Widget> children = [
    Widget1(),
    Widget2(),
    Widget3(),
    Widget4(), 
    Widget5(),
  ];

  @override
  Widget build(BuildContext context) {
    return Provider<MyUser>(
      create: (BuildContext context) {
        return widget.user;
      },
      child: Scaffold(
        bottomNavigationBar: BottomNavigationBar(
        currentIndex: selectedIndex,
        onTap: (index) => setState(() {
          selectedIndex = index;
        }),            
         ...
        ),
        body: children[selectedIndex],
      ),
    );
  }
}

Widget1:

class Widget1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    MyUser user = Provider.of<MyUser>(context);

    return Scaffold(
    ...
    )
   }
 }

I am not able to understand why this is an issue since Scaffold, which eventually has Widget1 as body is the child of Provider.

Please help me figure this out. Thanks in advance.



Solution 1:[1]

Try this snippet if you get some hints. Call it like.....FirstPage(user: MyUser()). What this does:

  1. In the appbar, there is an action which changes the widget. Tried this to check if the widget renders and selects the proper index.
  2. There is a Click button under the widget, which changes the change notifier variable and sees that the widget takes the change and rebuilds. This is just a check.
class MyUser extends ChangeNotifier {
    String something = "Something";

    _changeAndNotify() {
    something = "Nothing";
    notifyListeners();
    }
    }

    class FirstPage extends StatefulWidget {
    FirstPage({required this.user});

    final MyUser user;

    @override
    _FirstPageState createState() => _FirstPageState();
    }

    class _FirstPageState extends State<FirstPage> {
    int selectedIndex = 0;
    final List<Widget> children = [
    Widget1(),
    Widget2(),
    Text("onething"),
    Text("anything"),
    ];

    @override
    Widget build(BuildContext context) {
    return ChangeNotifierProvider<MyUser>(
      create: (BuildContext context) {
        return widget.user;
      },
      child: Scaffold(
        appBar: AppBar(
          actions: [
            ElevatedButton(
                onPressed: () {
                  setState(() {
                    selectedIndex = 1;
                  });
                },
                child: Text("Change Widget"))
          ],
        ),
        body: Column(
          children: [
            children[selectedIndex],
            ElevatedButton(
                onPressed: () {
                  widget.user._changeAndNotify();
                },
                child: Text("Click"))
          ],
        ),
      ),
      );
      }
      }

     class Widget1 extends StatelessWidget {
     @override
     Widget build(BuildContext context) {
     MyUser user = Provider.of<MyUser>(context);

     return Text("widget1:${user.something}");
     }
    }

    class Widget2 extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    MyUser user = Provider.of<MyUser>(context);

    return Text("widget2:${user.something}");
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 General Grievance