Flutter - Provider, State and Sqflite - the right way?

Viewed 26

Consider simple scenario, where there are 2 domain classes Parent and Child, and an AppState. All is stored in SqfLite.

class Parent extends ChangeNotifier {
  int id;
  String name;
  List<Child> children;
}

class Child extends ChangeNotifier {
  int id;
  String name;
}

and AppState

class AppState extends ChangeNotifier {
  List<Parent> parents;
}

The above model is of course simplified.

Now let say we have following operations:

  • add new parent
  • remove parent
  • add child to parent
  • remove child
  • update parent name
  • update child name

This can be achieved by simple methods, e.g.:

class Parent extends ChangeNotifier {
  int id;
  String name;
  List<Child> children;
}

addChild(Child c) {
  children.add(c);
  notifyListeners(); // make sure UI refreshes
}

So far so good.

Now goes the question: what is best pattern to make AppState to be in synch with data in DB? (Every time state changes -> to write the data to DB, so it is persisted).

Option 1

Access DB directly from domain classes:

in Parent.dart

Future<void> addChild(Child c) async {
  children.add(c);
  await DBHelper.addChildToParent(this, c);
  notifyListeners(); // make sure UI refreshes
}

Option 2

Access DB only from AppState:

in app_state.dart

Future<void> addChildToParent(Parent p, Child c) async {
  p.children.add(c);
  await DBHelper.addChildToParent(p, c);
  notifyListeners(); // make sure UI refreshes
}

In other words:

  1. Should domain classes have direct access/reference to DB?
  2. Should AppState be the only one that has access to DB?
  3. or is there other option?
1 Answers

I would suggest looking at stateful widgets.

The format is along this line

class Parent extends StatefulWidget{
// Define widget global variables here
  @override
  _ParentState createState() => _ParentState();
}
class _ParentState extends State<Parent>{
  //Other aspects of the widget including all children widgets
  setState({//You can then do your database sync from here});
}

If it were me, I would write a service class to handle all of the database work passing the parent/child data to it. but the setState() function will keep everything in sync. At least it does for my flutter app.

I did find (this interesting article)[https://blog.logrocket.com/flutter-sqlite-how-to-persist-data/] which describes your use case using stateful widgets and a "helper" (service) class.

Related