Как периодически получать данные из API (CoinGecko) во Flutter. -С Риверподом-
Я хочу получить данные от монетного геккона с помощью его API. С использованиемFutureProvider
сделать это. FutureProvider получает данные только один раз. Таким образом, данные приходят, и пользовательский интерфейс успешно строится. Однако я хочу прослушивать все изменения по каждой криптовалюте и перестраивать виджет. Я использую FutureProvider от Riverpod . Если бы я мог отправить запрос в службу и получать данные каждые 15 секунд и перестраивать пользовательский интерфейс, это решило бы мою проблему. Но я не мог этого сделать. Более того, я хочу узнать, как это сделать наиболее эффективно, правильно ли я иду? Любая помощь приветствуется. :)
final marketProvider = FutureProvider<List<Coin>>(
(ref) async => await DataService().fetch_coin_data(),
);
class CoinListPage extends ConsumerWidget {
const CoinListPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
AsyncValue<List<Coin>> coinList = ref.watch(marketProvider);
return Scaffold(
appBar: AppBar(
title: const Text("T I T L E"),
),
body: Center(
child: coinList.when(
data: (data) => CoinList(coinList: data),
error: (e, stack) => Text('Error: $e'),
loading: () => const CircularProgressIndicator(),
),
),
);
}
}
Future<List<Coin>> fetch_coin_data() async {
List<Coin> _coinList = <Coin>[];
final resp = await http.get(Uri.parse(
"https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=10&page=1&sparkline=false&price_change_percentage=24h"));
if (resp.statusCode == 200) {
// If the call to the server was successful, parse the JSON
List<dynamic> decoded = json.decode(resp.body);
for (dynamic coin in decoded) {
_coinList.add(Coin.fromJson(coin));
}
return _coinList;
} else {
// If that call was not successful, throw an error.
throw Exception('Request Error!');
}
}
Я не мог понять, какого провайдера мне использовать для этой цели. Любая помощь приветствуется!
1 ответ
предназначен для решения простых вариантов использования. Для более сложных сценариев рассмотрите возможность использования .
FutureProvider
возвращает , так что мы можем создатьStateNotifierProvider
с типом состоянияAsyncValue
, который будет обновлять данные выборки и обновлять состояние каждые 15 секунд.
final marketProvider = StateNotifierProvider<MarketNotifier, AsyncValue>((ref) {
return MarketNotifier();
});
class MarketNotifier extends StateNotifier<AsyncValue> {
MarketNotifier() : super(const AsyncValue.loading()) {
fetchLoopWithDelay(const Duration(seconds: 15));
}
Future<void> fetchLoopWithDelay(Duration delay) async {
while (true) {
try {
final data = await DataService().fetch_coin_data();
state = AsyncValue.data(data);
} catch (e) {
state = AsyncValue.error(e, StackTrace.current);
}
await Future.delayed(delay);
}
}
}