Home > Enterprise >  Why RiverPod FutureProvider does not make the Drawer to be rebuilt automatically
Why RiverPod FutureProvider does not make the Drawer to be rebuilt automatically

Time:06-29

My application has a Drawer that contains options per company branch, which are loaded from a repository using a FutureProvider provider. Using provider.when(loading:...), a message is shown while data is retrieved, but it is never replaced by the ListView with proper branches options, as I thought it would happen. I have to close the drawer, and open it again, for the data:... part of the when to be run.

This is the definition of the provider:

final branchRepositoryProvider = FutureProvider<BranchRepository>((ref) async {
  var repository = await BranchRepository.create();
  developer.log('BranchRepositoryProvider created.');
  return repository;

And this is the code that makes use of it:

class NavigationDrawer extends ConsumerWidget {
  const NavigationDrawer({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    AsyncValue<BranchRepository> provider =
        ref.read(repositories.branchRepositoryProvider);
    developer.log('Got branch provider.');
    return Drawer(
      child: ListView(
        padding: EdgeInsets.zero,
        children: <Widget>[
              DrawerHeader(...),
            ]  
            provider.when(
                data: (repository) => branchOptions(context, repository),
                loading: () =>
                    [const ListTile(title: Text('Reading the database...'))],
                error: (e, s) => [
                  ListTile(title: Text('Something when wrong:\n$e'))]),
      ),
    );
  }

  List<ListTile> branchOptions(
      BuildContext context, BranchRepository repository) {
    developer.log('Creating branch options...');
    var branches = getBranches(repository);
    ...
  }

  Map<int, String> getBranches(BranchRepository repository) {
    developer.log('Iterating over ids...');
    ...
  }
}

Messages in functions branchOptions(...) and getBranches(...) are shown only after the second click.

CodePudding user response:

I see you're using ref.read in a builder. In general, you should use ref.watch in a builder, and ref.read only for callbacks. Otherwise, the builder isn't set to rebuild when the value changes.

CodePudding user response:

As Randal Schwartz suggested, my mistake was using ref.read instead of ref.watch, as

AsyncValue<BranchRepository> provider =
    ref.watch(repositories.branchRepositoryProvider);

With that change, it is working now.

  • Related