Could not find the correct Provider<...> above this ContactsPage Widget

Viewed 2076

I'm experimenting with Flutter and I'm trying to build a simple app using the Providers pattern.

My Problem

I am trying to access a provider in one of the widgets and I'm getting this error once I get the required provider in the stateful widget class. I can't figure out what am I doing wrong here.

Error

Error: Could not find the correct Provider<ContactProvider> above this ContactsPage 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 ContactsPage is under your MultiProvider/Provider<ContactProvider>.
  This usually happens when you are creating a provider and trying to read it immediately.

...

The Code

main.dart

import 'package:ProvidersExample/provider_list.dart';
void main() async => runApp(Home());


class Home extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
        providers: providerList,
        child: MaterialApp(
          home: ContactsPage(),
        )
      );
  }
}

providers_list.dart

List<SingleChildWidget> providerList = [
  ChangeNotifierProvider(
    create: (_) => ContactProvider(),
    lazy: false,
  )
];

The provider: contact_provider.dart

class ContactProvider extends ChangeNotifier{
  List<Contact> _contactList = [];

  // getter
  List<Contact> get contacts {
    return [..._contactList];
  }

  // setter
  set contacts(List<Contact> newContacts) {
    _contactList = newContacts;
    notifyListeners();
  }
  ...

The Widget contacts_page.dart

class ContactsPage extends StatefulWidget {

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

class _ContactsPageState extends State<ContactsPage> {

  @override
  void initState(){
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    // This line throws the error
    ContactProvider _provider = Provider.of<ContactProvider>
      (context, listen:false);

    return Scaffold(
      appBar: AppBar(
        title: Text(
     ...
2 Answers

I think the reason is that you are referencing a list of providers which were created outside in provider_list.dart which does not have access to your context from your widget tree.

Try this instead:

   List providerList(context) {
    return [
      ChangeNotifierProvider(
        create: (context) => ContactProvider(),
        lazy: false,
      )
    ];
  }

providerList() is now a method that takes in context, and uses that context to register your providers, and return it.

You should specify the type <T> when creating your provider so it knows which type you are looking for in the widget tree.

List<SingleChildWidget> providerList = [
  ChangeNotifierProvider<ContactProvider>(
    create: (_) => ContactProvider(),
    lazy: false,
  )
];
Related