'Call a function on load using RiverPod and StateNotifiers

I was following the Resocoder tutorial on how to manage states with RiverPod and StateNotifier.

What kind of trips me is as to how to call the .getWeather on an initial load with some let say default value. The example only illustrates using context.read(..) in the onPressed(..) function which is what is recommended in the riverpod docs.

But then how do you actually make a call on load, since that would mean calling context.read in the build method which is highly discouraged. (mentioned in the last part of this section)



Solution 1:[1]

Because .getWeather is a Future function, you can actually add the future initialization inside the constructor of WeatherNotifier and let it update the state itself.

final weatherNotifierProvider = StateNotifierProvider(
  (ref) => WeatherNotifier(ref.watch(weatherRepositoryProvider)),
);


class WeatherNotifier extends StateNotifier<WeatherState> {
  final WeatherRepository _weatherRepository;

  WeatherNotifier(this._weatherRepository) : super(WeatherInitial()){
    getWeather('some city name'); // add here
  }

  Future<void> getWeather(String cityName) async {
    try {
      state = WeatherLoading();
      final weather = await _weatherRepository.fetchWeather(cityName);
      state = WeatherLoaded(weather);
    } on NetworkException {
      state = WeatherError("Couldn't fetch weather. Is the device online?");
    }
  }
}

Solution 2:[2]

Look into .family modifier, you can pass data to a provider returned data/state.

https://riverpod.dev/docs/concepts/modifiers/family

Listening to state with a parameter:

final state = ref.watch(myProvider('my arg'));

Creating a provider:

myProvider = StateNotifierProvider.family<String>((ref, arg) => "Hello $arg");

If you print state you'll get

print(state); //prints "Hello my arg"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 yellowgray
Solution 2 Defuera