0

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?
Maciej Pszczolinski
  • 1,623
  • 1
  • 19
  • 38

1 Answers1

0

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.

Paul Stoner
  • 1,359
  • 21
  • 44
  • Using stateful widget is even worse idea, as you don't have centralised state, thus it's harder to manage. That's why I'm using Provider approach. – Maciej Pszczolinski Sep 16 '22 at 04:58
  • What kind of app are you building that you need to use a central state manager? And really you should criticize someone else's approach like that. – Paul Stoner Sep 16 '22 at 14:15
  • As far as I learnt flutter - the key to manage state in the app is to actually lift the state up (e.g. using Provider) in any flutter app. Widget state (StatefullWidget) and AppState are two totally separate things. – Maciej Pszczolinski Sep 17 '22 at 11:03