I am currently making the Udacity Sunshine project in Flutter. I have two different provider to fetch current temperature and daily forecasts.
I want to combine the two providers and make a new single provider called weatherProvider.
File: weather_data.dart
import 'package:app/models/current_weather_data.dart';
import 'one_call_weather_data.dart';
class WeatherData {
final OneCallWeatherData oneCallWeatherData;
final CurrentWeatherData currentWeatherData;
WeatherData({
required this.oneCallWeatherData,
required this.currentWeatherData,
});
}
File:weather_provider.dart
import 'package:app/models/current_weather_data.dart';
import 'package:app/models/one_call_weather_data.dart';
import 'package:app/services/weather.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
var oneCallWeatherProvider = FutureProvider<OneCallWeatherData>((ref) async {
return await WeatherService.getOneCallWeatherData();
});
var currentWeatherProvider = FutureProvider<CurrentWeatherData>((ref) async {
return await WeatherService.getCurrentWeatherData();
});
final weatherProvider = FutureProvider<WeatherData>((ref) async {
final currentWeatherData = ref.watch(currentWeatherProvider);
final onecallWeatherData = ref.watch(oneCallWeatherProvider);
// How to return WeatherData here??
});
In above providers, I am trying to fetch the data from two future providers and get the objects for currentWeatherData and onecallWeatherData. I would like to wait for them here and get the two data. The two data sends error if error as well. Now, how to send the data to UI from the provider so that I can do .when(data:xx, error: xx, loading: xx)
on the widget and get both data safely?
Note: I can get the whole data without combining the providers by making a single FutureProvider and awaiting the two futures using Future.wait()
. However, I am trying to learn to combine the providers. So, any solution from the community is greatly apprecitated.
CodePudding user response:
You should do it in this way.
Example:
final weatherProvider = FutureProvider<WeatherData>((ref) async {
final currentWeatherData = ref.watch(currentWeatherProvider);
final onecallWeatherData = ref.watch(oneCallWeatherProvider);
return WeatherData(
oneCallWeatherData: onecallWeatherData,
currentWeatherData: currentWeatherData,
);
});
CodePudding user response:
You can use provider.future
to obtain a Future
which you can then await
This allows you to write:
final weatherProvider = FutureProvider<WeatherData>((ref) async {
final currentWeatherData = ref.watch(currentWeatherProvider.future);
final onecallWeatherData = ref.watch(oneCallWeatherProvider.future);
return WeatherData(
oneCallWeatherData: await onecallWeatherData,
currentWeatherData: await currentWeatherData,
);
});