Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter problem with finding provider context

I have a problem with Flutter Provider pattern. After user is redirected to a new screen, the provider could not be found.

Following my previous question (Could not find the correct provider above this widget) I wrote this code:

class NewRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final title = 'Tap to select';
    return MaterialApp(
        title: title,
        home: Scaffold(
          appBar: AppBar(
            title: Text(title),
          ),
          body: NewRouteBody()
        ));
  }
}

class NewRouteBody extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var user = Provider.of<UserRepository>(context);
    return ListView(...)

I did same thing but I get again the error which says that it could not find the correct provider above this widget (NewRouteBody).

Tried to fix it somehow, Googled the answer for a few hours but without success...

Any help is appreciated.

EDIT

This is UserRepository which contains pattern:

class UserRepository with ChangeNotifier {
  User user;
  Status _status = Status.Uninitialized;

  Status get status => _status;
  User get getUser => user;
...}

EDIT 2:

Code snippet with ChangeNotifier:

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<UserRepository>(
      builder: (context) => UserRepository.instance(),
      child: Consumer<UserRepository>(
        builder: (context, UserRepository userRepository, _) {
          switch (userRepository.status) {
            case Status.Uninitialized:
              return Login();
            case Status.Unauthenticated:
              return Login();
            case Status.Authenticating:
            case Status.Authenticated:

              if(userRepository.getUser.isPrefSet == 0){
                return Selection();
              }
              return Dashboard();
          }
        },
      ),
    );
  }
}
like image 927
harunB10 Avatar asked Jul 28 '19 21:07

harunB10


People also ask

How do you define context in flutter?

– Context is a link to the location of a widget in the tree structure of widgets. – Context can belong to only one widget. – If a widget has child widgets, then the context of the parent widget becomes the parent context for the contexts of direct child elements.

How do you use provider value in flutter?

Example Using Provider So, first to get the String value created in the main. dart , all we have to do is call Provider. of<String>(context) , the of() method here will obtain the nearest Provider up its widget tree and returns its value.

How to resolve could not find the correct provider above widget in flutter?

How to Resolve could not find the correct provider above widget In Flutter? Try extracting part of your widget tree that lies below Scaffold to a separate widget. The context you are using now is used to build your top-level widget which does not Navigator yet.

What is a provider in flutter?

In simple terms, provider is a wrapper around Inherited Widgets, which was explained in the previous tutorial Using Inherited Widgets In Flutter. After creating a project, navigate to the pubspec.yaml file and add the following:

What is a blocprovider in flutter?

How to Solve BlocProvider.of () Called With a Context In Flutter ? A BLoC stands as a middleman between a source of data in your app e.g an API response and widgets that need the data.

How to use inherited widget in flutter?

Let’s see an example of using InheritedWidget, using the counter application that is generated when you run flutter create new_project. First inside the main.dart we do the following: So here we define the Provider at the top of the widget tree, and we create an object of type String.


2 Answers

The issue is:

Your ChangeNotifierProvider is located inside Home, but you are trying to access it outside Home.

Providers are scoped. Which means that if it's located inside a widget tree, only its descendants can access it. As such, in your code, only Home can read from the provider.

To fix that, move the provider above MaterialApp:

ChangeNotifierProvider<UserRepository> (
  builder: (context) => UserRepository(),
  child: MaterialApp(
    home: Home(),
  ),
)
like image 118
Rémi Rousselet Avatar answered Oct 12 '22 03:10

Rémi Rousselet


You first need to create the Provider and place in the tree above the usage. for example, in your case:

  Widget build(BuildContext context) {
final title = 'Tap to select';
return MaterialApp(
    title: title,
    home: Scaffold(
        appBar: AppBar(
          title: Text(title),
        ),
        body: Provider<UserRepository> (
          builder: (context) => UserRepository(),
            dispose: (context, val) => val.dispose(),
            child: NewRouteBody())
    ));

}

like image 2
MozesM Avatar answered Oct 12 '22 03:10

MozesM