Could not find the correct Provider<SupervisorProvider> above this AddSupervisor Widget

197 Views Asked by At

HomeSupervisor class

    import 'package:flutter/material.dart';
    import 'package:fyp/provider/supervisorProvider.dart';
    import 'package:fyp/screen/AddSupervisor.dart';
    import 'package:fyp/sidebar/AdminDrawer.dart';
    import 'package:provider/provider.dart';

    class HomeSupervisor extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    return ChangeNotifierProvider(
        create: (context) => SupervisorProvider(),
      child: Scaffold(
        appBar: AppBar(
            title: Text('Supervisor'),
          actions: <Widget>[
            IconButton(
                icon: Icon(
                  Icons.add,
                  color: Colors.white,
                ),
                onPressed:(){
                  Navigator.push(context, MaterialPageRoute(builder: (context) => AddSupervisor()));
                })
          ],
        ),
        drawer: AdminDrawer(),
      ),
    );
  }
}

AddSupervisor class

    import 'package:flutter/material.dart';
    import 'package:fyp/provider/supervisorProvider.dart';
    import 'package:provider/provider.dart';

    class AddSupervisor extends StatefulWidget {


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

    class _AddSupervisorState extends State<AddSupervisor> {


    bool loading = false;

    @override
    Widget build(BuildContext context) {
    final supervisorProvider = Provider.of<SupervisorProvider>(context);
     return Scaffold(
     appBar: AppBar(
       title: Text('Supervisor'),
     ),
     body: SingleChildScrollView(
       child: Form(
         child: Column(
           crossAxisAlignment: CrossAxisAlignment.start,
           children: <Widget>[
             SizedBox(height: 10.0),
             TextFormField(
               decoration: InputDecoration(labelText: 'Name',border: OutlineInputBorder()),
               keyboardType: TextInputType.text,
               validator: (value) => value.isEmpty ? 'Enter a name': null,
               onChanged: (value) {
                supervisorProvider.changeName(value);
               },
             ),
             SizedBox(height: 5.0),
             TextFormField(
               decoration: InputDecoration(labelText: 'Email',border: OutlineInputBorder()),
               keyboardType: TextInputType.emailAddress,
               validator: (value) => value.isEmpty ? 'Enter a email': null,
               onChanged: (value) {
                 supervisorProvider.changeEmail(value);
               },
             ),
             SizedBox(height: 5.0),
             TextFormField(
               decoration: InputDecoration(labelText: 'Number Phone',border: OutlineInputBorder()),
               keyboardType: TextInputType.number,
               validator: (value) => value.isEmpty ? 'Enter a Phone': null,
               onChanged: (value) {
                 supervisorProvider.changePhone(value);
               },
             ),
             SizedBox(height: 5.0),
             TextFormField(
               decoration: InputDecoration(labelText: 'Ic Number ',border: OutlineInputBorder()),
               keyboardType: TextInputType.number,
               validator: (value) => value.isEmpty ? 'Enter a ic number': null,
               onChanged: (value) {
                 supervisorProvider.changeIcNumber(value);
               },
             ),
             SizedBox(height: 10.0),
             RaisedButton(
               color: Colors.grey,
               textColor: Colors.black,
               child: Text("Submit"),
               onPressed:(){
                 supervisorProvider.addSupervisor();
                 Navigator.of(context).pop();
               }
             ),
           ],
         ),
       ),
     ),
   );
  }
}

SupervisorProvider class

import 'package:flutter/cupertino.dart';
import 'package:fyp/model/Supervisor.dart';
import 'package:fyp/service/database.dart';
import 'package:uuid/uuid.dart';

class SupervisorProvider with ChangeNotifier{

  final DatabaseService db = DatabaseService();
  String _name;
  String _email;
  String  _icNumber;
  String _numberphone;
  var uuid = Uuid();

  // getters
String get name => _name;
String get email => _email;
String get icNo => _icNumber;
String get nophone => _numberphone;

// setters
   changeName(String value){
     _name=value;
     notifyListeners();
   }
  changeEmail(String value){
    _email=value;
    notifyListeners();
  }
  changePhone(String value){
    _numberphone=value;
    notifyListeners();
  }
  changeIcNumber(String value){
    _icNumber=value;
    notifyListeners();
  }

  addSupervisor(){
    var NewSupervisor = Supervisor(name: name, email: email, icNo: icNo, nophone: nophone, supervisorId: uuid.v4());
      db.addSupervisor(NewSupervisor);
  }
}

then i got my error like this

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

This likely happens because you used a BuildContext that does not include the provider of your choice. There are a few common scenarios:

  • 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 AddSupervisor is under your MultiProvider/Provider. This usually happen when you are creating a provider and trying to read it immediately.

    For example, instead of:

    Widget build(BuildContext context) { return Provider( create: (_) => Example(), // Will throw a ProviderNotFoundError, because context is associated // to the widget that is the parent of Provider<Example> child: Text(context.watch()), ), }

    consider using builder like so:

    Widget build(BuildContext context) { return Provider( 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()), } ), }

If none of these solutions work, consider asking for help on StackOverflow: https://stackoverflow.com/questions/tagged/flutter The relevant error-causing widget was: AddSupervisor file:///D:/Android_project/fyp/lib/screen/home/HomeSupervisor.dart:20:83

is there anything that I missing? I need someone help

2

There are 2 best solutions below

2
On

if you want to use Some class with provider you have to provide one instance of your class to the provider,

for example i do this


class App extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        Provider<ThemeStore>(
          create: (_) => ThemeStore(),
        ),
        Provider<AuthStore>(
          create: (_)=> AuthStore(),
        ),
      ],
      builder: (context,w){
        return MaterialApp(
          title: "App",
          theme: context.watch<ThemeStore>().selectedThemeData,
          initialRoute: "/",
          onGenerateRoute: RouteManager.onGenerate,
        );
      },
    );
  }
}

so further down the widget tree i can access the two stores using Provider.of(context)

0
On
 class SearchingScreen extends StatelessWidget {
 AuthBase authBase = AuthBase();
@override
Widget build(BuildContext context) {
 return ChangeNotifierProvider(
  create: (_) => UserModel(),
  child:HomeView(),
);

} }