1

Basically I am trying to combine a FutureProvider and a StateNotifierProvider into one single Provider with Riverpod. I know that there is already a question for a similar thing, but this is a bit more complex.

The scenario: The user is able to set a location by himself / herself that has priority 1. Only if there is no location set (e.g. when the App launches) the current location should be fetched based on an async function. So the users are able to override their location whenever they want.

What I would like to achieve in the end is the following: The set or fetched location can dynamically change in a widget, so it automatically changes e.g. a displayed location name whenever the set location is removed, so it shows a loading animation and in the end the newly fetched location and vice versa like .when().

For now, I have created a FutureProvider that reads two dedicated providers:

final currentFetchedLocationProvider = FutureProvider<LocationModel?>((ref) => 
    ref.read(locationServiceProvider).getCurrentLocation());

final currentSelectedLocationProvider = getNullableLocationNotifier(null);

final currentLocationProvider = FutureProvider<LocationModel?>((ref) {
  LocationModel? selectedLocation = ref.watch(currentSelectedLocationProvider);

  if (selectedLocation != null) return selectedLocation;

  return ref.watch(currentFetchedLocationProvider.future);
});

I also would like to get the location in another function that fetches data asynchronously based on that value (so no widget). If the value was already set or initially created I do not want the device to fetch the value again if it is already there. If a fetching is ongoing, it should just continue at that point and in the end grab the value. And of course if there is no value, yet.

This is what I tried for now in my DatabaseService class, but this does the fetching again even if there is already a value set I guess:

class DatabaseService implements BaseDatabaseService {

  final Reader _read;

  const DatabaseService(this._read);

  // IMPORTANT
  Future<LocationModel?> get currentLocation => _read(currentLocationProvider.future);

  ...

  Future<Map<String, dynamic>?> getBasicEventJson(String id) async {
      // IMPORTANT
      LocationModel? location = await currentLocation;
  }
Florian Leeser
  • 590
  • 1
  • 6
  • 20

0 Answers0