Home > Net >  Flutter Provider explanation : Exception has occurred. ProviderNotFoundException
Flutter Provider explanation : Exception has occurred. ProviderNotFoundException

Time:03-21

I'm new to flutter. I've got the below code and it's not running. I know how to fix the error (one solution). But I wanted to understand the concept here of why it's not running. Also, all the other different solutions to fix this issue.

I would like to know much detailed explanation about the below code why the error occurred?

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider<String>(
      create: (context) => "Passing Data",
      child: MaterialApp(
        title: Provider.of<String>(context),
        home: HomePage(),
      ),
    );
  }
}

CodePudding user response:

You can read up on BuildContext, Provider and InheritedWidget, but I also can offer a condensed explanation:

You cannot use the Provider within the same widget in which you're returning it. It must be inherited (i.e. the Provider must come down from a parent or ancestor widget) or have a separate context. You must either create a separate widget above (i.e. a parent widget) that then includes the MaterialApp if you still want to use it there. This is mostly because of the Context reference. The context is used to pull data from the widget's ancestors (in this case, a provided value from above), and Provider is nothing more than a wrapper around InheritedWidget, therefore in order to fetch the provided value, the context must be inherited or be its own context.

In your case, the Provider must be either located on a parent widget so you can inherit the value being handed down to you, or you must use something like a Consumer widget or a Builder widget which supply their own context, but never use the same context both for injecting and fetching the provider.

You either can do it like this, where the Builder widget supplies its own context:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider<String>(
      create: (context) => "Passing Data",
      child: Builder(
        builder: (context) {
          return MaterialApp(
            title: Provider.of<String>(context),
            home: HomePage()
          );
        } 
      ),
    );
  }
}

or like this, where you see in the runApp how we wrap the Provider around the MyApp, creating a hierarchy, allowing for the context to be inherited by the MyApp widget, from which you can safely fetch the provided value.

void main() {
  runApp(
    Provider<String>(
      create: (context) => "Passing Data",
      child: MyApp()
    )
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: Provider.of<String>(context),
      home: HomePage(),
    );
  }
}
  • Related