Error related to Flutter provider package

1,533

Solution 1

Because you have to declare the provider class above the class were your using it , if u find this ans crt mark it as crt

 @override
Widget build(BuildContext context) {
return MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (ctx) => MyUser(),),
    
  ],
  child: MaterialApp());

Solution 2

You have to warp the parent class with the provider class you are using inside. For doing so the easiest way is to add a static method in widget havingMaterialPageRoute which helps to navigate to SettingsForm screen.

class SettingsForm extends StatefulWidget {

  static Widget getWidget() {
    return new Provider(
        create: (_) => MyUser(),
        child: ChangeNotifierProvider(
          create: (BuildContext context) => MyUser(),
          builder: (_,_) => SettingsForm()
        ),
     );
  }

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

To open SettingsForm screen just call getRoute function on button pressed. Check the below code.

Open SettingsForm screen from Home screen

 void _showSettingsPanel() {
      showModalBottomSheet(context: context, builder: (context) {
        return Container(
          padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 60.0),
          child: SettingsForm.getWidget(), <-- Here
        );
      });
    }
Share:
1,533
Mike Osborn
Author by

Mike Osborn

Updated on December 17, 2022

Comments

  • Mike Osborn
    Mike Osborn over 1 year

    I am building a setting widget in my flutter app and I am getting this error :

    Error: Could not find the correct Provider above this SettingsForm Widget

    Update Adding whole debug snippet:

    Launching lib\main.dart on AOSP on IA Emulator in debug mode...
    
    ════════ Exception caught by widgets library ═══════════════════════════════════
    The following ProviderNotFoundException was thrown building SettingsForm(dirty, state: _SettingsFormState#c73b8):
    Error: Could not find the correct Provider<MyUser> above this SettingsForm 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 SettingsForm is under your MultiProvider/Provider<MyUser>.
      This usually happens when you are creating a provider and trying to read it immediately.
    
      For example, instead of:
    
      ```
      Widget build(BuildContext context) {
        return Provider<Example>(
          create: (_) => Example(),
          // Will throw a ProviderNotFoundError, because `context` is associated
          // to the widget that is the parent of `Provider<Example>`
          child: Text(context.watch<Example>()),
        ),
      }
      ```
    
      consider using `builder` like so:
    
      ```
      Widget build(BuildContext context) {
        return Provider<Example>(
          create: (_) => Example(),
          // we use `builder` to obtain a new `BuildContext` that has access to the provider
          builder: (context) {
            // No longer throws
            return Text(context.watch<Example>()),
          }
        ),
      }
      ```
    
    If none of these solutions work, consider asking for help on StackOverflow:
    https://stackoverflow.com/questions/tagged/flutter
    
    
    The relevant error-causing widget was
    SettingsForm
    When the exception was thrown, this was the stack
    #0      Provider._inheritedElementOf
    #1      Provider.of
    #2      _SettingsFormState.build
    #3      StatefulElement.build
    #4      ComponentElement.performRebuild
    ...
    ════════════════════════════════════════════════════════════════════════════════
    

    i UPDATED IT AND ADDED SOME EXTRA CODE SO YOU CAN SEE BETTER

    setting.dart:

    class SettingsForm extends StatefulWidget {
      @override
      _SettingsFormState createState() => _SettingsFormState();
    }
    
    class _SettingsFormState extends State<SettingsForm> {
      final _formKey = GlobalKey<FormState>();
      final List<String> sugars = ['0', '1', '2', '3', '4'];
      final List<int> strengths = [100, 200, 300, 400, 500, 600, 700, 800, 900];
    
      // form values
      String? _currentName;
      String? _currentSugars;
      int? _currentStrength;
    
      @override
      Widget build(BuildContext context) {
        MyUser user = Provider.of<MyUser>(context);
    
        return StreamBuilder<UserData>(
            stream: DatabaseService(uid: user.uid).userData,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                UserData? userData = snapshot.data;
                return Form(
                  key: _formKey,
                  child: Column(
                    children: <Widget>[
                      Text(
                        'Update your brew settings.',
                        style: TextStyle(fontSize: 18.0),
                      ),
                      SizedBox(height: 20.0),
                      TextFormField(
                        initialValue: userData!.name,
                        decoration: textInputDecoration,
                        validator: (val) =>
                            val!.isEmpty ? 'Please enter a name' : null,
                        onChanged: (val) => setState(() => _currentName = val),
                      ),
                      SizedBox(height: 10.0),
                      DropdownButtonFormField<String>(
                        value: _currentSugars ?? userData.sugars,
                        decoration: textInputDecoration,
                        items: sugars.map((sugar) {
                          return DropdownMenuItem(
                            value: sugar,
                            child: Text('$sugar sugars'),
                          );
                        }).toList(),
                        onChanged: (val) => setState(() => _currentSugars = val),
                      ),
                      SizedBox(height: 10.0),
                      Slider(
                        value: (_currentStrength ?? userData.strength).toDouble(),
                        activeColor:
                            Colors.brown[_currentStrength ?? userData.strength],
                        inactiveColor:
                            Colors.brown[_currentStrength ?? userData.strength],
                        min: 100.0,
                        max: 900.0,
                        divisions: 8,
                        onChanged: (val) =>
                            setState(() => _currentStrength = val.round()),
                      ),
                      ElevatedButton(
                          style:
                              ElevatedButton.styleFrom(primary: Colors.pink[400]),
                          child: Text(
                            'Update',
                            style: TextStyle(color: Colors.white),
                          ),
                          onPressed: () async {
                            if (_formKey.currentState!.validate()) {
                              await DatabaseService(uid: user.uid).updateUserData(
                                  _currentSugars ?? snapshot.data!.sugars,
                                  _currentName ?? snapshot.data!.name,
                                  _currentStrength ?? snapshot.data!.strength);
                              Navigator.pop(context);
                            }
                          }),
                    ],
                  ),
                );
              } else {
                return Loading();
              }
            });
      }
    }
    

    UPDATE: I AM INCLUDING THE HOME.DART FILE THAT INCLUDES THE 'SETTINGFORM' WIDGET home.dart :

    class Home extends StatelessWidget {
    
      final AuthService _auth = AuthService();
    
      @override
      Widget build(BuildContext context) {
    
        void _showSettingsPanel() {
          showModalBottomSheet(context: context, builder: (context) {
            return Container(
              padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 60.0),
              child: SettingsForm(), <-- Here
            );
          });
        }
    
        return StreamProvider<List<Brew>?>.value(
          value: DatabaseService(uid: '').brews,
          initialData: null,
          child: Scaffold(
            backgroundColor: Colors.brown[50],
            appBar: AppBar(
              title: Text('Brew Crew'),
              backgroundColor: Colors.brown[400],
              elevation: 0.0,
              actions: <Widget>[
                TextButton.icon(
                  icon: Icon(Icons.person),
                  label: Text('logout'),
                  onPressed: () async {
                    await _auth.signOut();
                  },
                ),
                TextButton.icon(
                  icon: Icon(Icons.settings),
                  label: Text('settings'),
                  onPressed: () => _showSettingsPanel(),
                )
              ],
            ),
            body: Container(
              decoration: BoxDecoration(
                image: DecorationImage(
                  image: AssetImage('assets/coffee_bg.png'),
                  fit: BoxFit.cover,
                ),
              ),
              child: BrewList()
            ),
          ),
        );
      }
    }
    

    user.dart:

    class MyUser {
    
      final String uid;
      
      MyUser({ required this.uid });
    
    }
    
    class UserData {
    
      final String uid;
      final String name;
      final String sugars;
      final int strength;
    
      UserData({ required this.uid, required this.sugars, required this.strength, required this.name });
    
    }
    

    Update Update 2 Error

    • Midhun MP
      Midhun MP almost 3 years
      Why did you defined that method inside the build ?
    • Mike Osborn
      Mike Osborn almost 3 years
      If you meant the provider class they are built inside widgets.
    • Midhun MP
      Midhun MP almost 3 years
      I mean that _showSettingsPanel method.
  • Mike Osborn
    Mike Osborn almost 3 years
    Can you briefly explain what's causing the problem?
  • PRATHIV
    PRATHIV almost 3 years
    if your using the provider class inside the widgets then you have to declare it above that class , so it's better to declare it top of all widgets , so declare it above MaterialApp
  • Mike Osborn
    Mike Osborn almost 3 years
    I am not using it in main.dart i am using it in setting_form.dart
  • Mike Osborn
    Mike Osborn almost 3 years
    Thnx for responding also i updated my code
  • Mike Osborn
    Mike Osborn almost 3 years
    I am getting some probs recently
  • Mike Osborn
    Mike Osborn almost 3 years
    Update i am using stream provider and the setting bar is in my home screen (home.dart) in the app
  • Mike Osborn
    Mike Osborn almost 3 years
    @Alphamerc getting error on change notifier provider pls see update screenshot in my q
  • TheAlphamerc
    TheAlphamerc almost 3 years
    Does the MyUser class extend the ChangeNotifier class?
  • Mike Osborn
    Mike Osborn almost 3 years
    I think I have created a 'UserData' class for setting widget
  • Mike Osborn
    Mike Osborn almost 3 years
    But MyUser gives the uid class object
  • TheAlphamerc
    TheAlphamerc almost 3 years
    MyUser class doesn't extend the ChangeNotifire class so you can't use MyUser user = Provider.of<MyUser>(context);
  • Mike Osborn
    Mike Osborn almost 3 years
    I tried to put 'UserData' instead of 'MyUser' but it didn't work out
  • Mike Osborn
    Mike Osborn almost 3 years
    still haven't found the answer to this question
  • Mike Osborn
    Mike Osborn almost 3 years
    I added the whole debug error can u fix it?