Flutter/Riverpod – StateNotifier – call state change before end of method – safe?

In my Flutter app I am using two providers to manage a list display…

  • a ‘goalListFutureProvider ‘ Future provider that retrieves the list of entries to display
  • a ‘goalCrudProvider’ StateNotifier provider that handles add/edit/delete actions on entries in the list

The code for the list provider is shown below, where state changes in the CRUD provider will trigger a refresh of the future list provider

final goalListFutureProvider = FutureProvider<List<GdGoal>>((ref) {
  ref.watch(goalSchedulingProvider);
  ref.watch(goalCrudProvider);
  final aSearch = ref.watch(goalListSearchProvider);
  return ref.watch(goalServiceProvider).find(aSearch);
});

Within my CRUD provider I am calling a state change as part of the process logic, the ‘update’ code is shown below..

class GdGoalNotifier extends StateNotifier<bool> {

  Future<bool> update(GdGoal aGoal) async {
    final aRes = await _goalService.update(aGoal);
    state = !state;
    return aRes;
  }

Within the ‘update’ method is it correct to call ‘state = !state’ before the end of the function call? Or should I break out this state refresh to a separate CRUD provider method?

>Solution :

It’s generally recommended to keep the state changes in a separate method within the CRUD provider, rather than having them within the update method. This is because it allows for more flexibility and better organization of the code.

Here is an example of how you could refactor your code:

class GdGoalNotifier extends StateNotifier<bool> {
Future<bool> update(GdGoal aGoal) async {
final aRes = await _goalService.update(aGoal);
refresh();
return aRes;
}

void refresh() {
state = !state;
}
}

This way, you can easily call the ‘refresh’ method whenever you want to refresh the list, without having to duplicate the state change code in multiple places.

By calling the ‘state = !state’ before the end of the function call, you will be changing the state before the update method is finished, this might cause some unexpected behavior.
Also, if you are updating goal in the DB, you should be updating the state after you get the confirmations from the DB that the update is successful, instead of just changing the state to trigger a rebuild.

It’s always better to keep the state change separate from the main function, so that it’s more manageable and testable.

Leave a Reply