Could not find correct provider above widget

Issue

I am relatively new to Flutter and am building an app that fetches data from an API and display it throughout the app on different widgets. I am using a Provider to perform the API calls and store the deserialized json in a property I then access in the initState function. Below is the widget tree of my main.dart, I want to then access the provider found here in the Dashboard page as this is where the value is required. I know what I am doing is wrong, but how much have I gotten it wrong?

  runApp(MaterialApp(
    home: LoginPage(),
    routes: routes,
  ));
}

class SampleApp extends StatefulWidget {
  @override
  SampleAppState createState() => SampleAppState();
}

class SampleAppState extends State<SampleApp> {
  int currentIndex = 0;
  final List<Widget> childPages = [
    Page1(),
    Page2(),
    Page3(),
    Page4()
  ];

  void onTapped(int index) {
    setState(() {
      currentIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) => APIProvider())
      ],
      child: Scaffold(
        body: childPages[currentIndex],
        bottomNavigationBar: BottomNavigationBar(
          onTap: onTapped,
          currentIndex: currentIndex,
          fixedColor: Colors.lightBlue,
          backgroundColor: Colors.white,
          type: BottomNavigationBarType.fixed,
          items: [
            BottomNavigationBarItem(
                icon: new Icon(Icons.dashboard),
                title: new Text('Page 1'),
                activeIcon: new Icon(
                  Icons.dashboard,
                  color: Colors.lightBlue,
                )),
            BottomNavigationBarItem(
                icon: new Icon(Icons.list),
                title: new Text('Page 2'),
                activeIcon: new Icon(
                  Icons.list,
                  color: Colors.lightBlue,
                )),
            BottomNavigationBarItem(
                icon: new Icon(Icons.collections_bookmark),
                title: new Text('Page 3'),
                activeIcon: new Icon(
                  Icons.collections_bookmark,
                  color: Colors.lightBlue,
                )),
            BottomNavigationBarItem(
                icon: new Icon(Icons.person),
                title: new Text('Page 4'),
                activeIcon: new Icon(
                  Icons.person,
                  color: Colors.lightBlue,
                )),
          ],
        ),
      ),
    );
  }
}

I then attempt to access the provider value in Page1 like so:

@override
  void initState() {
    valueFromProvider =
        Provider.of<APIProvider>(context).providerValue;
    super.initState();
  }

Perhaps this is happening because the provider value I attempt to access in the Page1 widget is null, would pre-loading my provider solve this?

Solution

You aren’t providing the Provider at the right time. In your case you add the MultiProvider at page1, but your context is already initialized so you can’t access it. In order to properly access it, you must move the MultiProvider to where you initialize the app like the following:

runApp(

MaterialApp(
    home: MultiProvider(
    providers: [
        ChangeNotifierProvider(create: (context) => APIProvider())
      ],
     child:LoginPage()
     ),
    routes: routes,
  ));

This should fix your issue.

Answered By – Gabe

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *