How to create a dependency for ChangeNotifierProvider and make it wait to complete?

Issue

I have ChangeNotifierProvider object that uses data stored sqflite asset database which need to be loaded at the beginning as future. The problem is that ChangeNotifierProvider doesn’t wait for future operation to complete. I tried to add a mechanism to make ChangeNotifierProvider wait but couldn’t succeed. (tried FutureBuilder, FutureProvider, using all together etc…)

Note : FutureProvider solves waiting problem but it doesn’t listen the object as ChangeNotifierProvider does. When I use them in multiprovider I had two different object instances…

All solutions that I found in StackOverflow or other sites don’t give a general solution or approach for this particular problem. (or I couldn’t find) I believe there must be a very basic solution/approach and decided to ask for your help. How can I implement a future to this code or how can I make ChangeNotifierProvider wait for future?

Here is my summary code;


class DataSource with ChangeNotifier {
  int _myId;
  List _myList;

  int get myId => _myId;
  List get myList => _myList;

  void setMyId(int changeMyId) {
    _myId = changeMyId;
    notifyListeners();
  }
  .... same setter code for myList object.
  
  DataSource(){initDatabase();}
  
  Future<bool> initDatabase() {
    .... fetching data from asset database. (this code works properly)
    return true;
  }
}

main.dart

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<DataSource>(
      create: (context) => DataSource(),
      child: MaterialApp(
        home: HomePage(),
      ),
    );
  }
}

Following code and widgets has this code part (it works fine)

return Consumer<DataSource>(
      builder: (context, myDataSource, child) {.......

Solution

There are multiple ways that you can achieve. The main point of it is that you should stick to reactive principle rather than trying to await the change. Say for example, you could change the state of boolean value inside the DataSource class when the ajax request changes

class DataSource extends ChangeNotifier{
  bool isDone = false;
  
  Future<bool> initDatabase(){
    //Do Whatever
    
    isDone = true;
    notifyListeners();
  }
}

Then you could listen to this change in the build method like so

  Widget build(BuildContext ctx){
    bool isDone = Provider.of<DataSource>(context).isDone;
    
    if(isDone){
      // render result
    }else{
      // maybe render loading
    }
  }

Answered By – forJ

Answer Checked By – Pedro (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.