I want to fetch price data of trading pairs specified inpriceList
from the public Binance API and create a dynamic List of Card widgets using API response.
I am failing at this step as the future
argument of FutureBuilder does not accept the list of Futures : List<Future<PriceListItem>> pliList
Thank you.
My code:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
));
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class PriceListItem {
final String pair;
final String price;
PriceListItem({
required this.pair,
required this.price,
});
factory PriceListItem.fromJson(Map<String, dynamic> json) {
return PriceListItem(
pair: json['symbol'],
price: json['price'],
);
}
}
class _HomePageState extends State<HomePage> {
List<String> pairList = [
"USTBUSD",
"USTUSDT",
"USDCBUSD",
"USDCUSDT",
"BUSDUSDT",
"BTCBUSD",
"USTBTC",
"BTCUSDT",
"BTCUSDC",
];
late Future<PriceListItem> pli;
late List<Future<PriceListItem>> pliList;
Future<PriceListItem> fetchPrice(String ticker) async {
final response = await http.get(Uri.parse(
"https://api.binance.com/api/v3/ticker/price?symbol=$ticker"));
if (response.statusCode == 200) {
return PriceListItem.fromJson(jsonDecode(response.body));
} else {
throw Exception("Failed to fetch price data.");
}
}
@override
void initState() {
pliList = [];
for (int i = 0; i < pairList.length; i ) {
pli = fetchPrice(pairList[i]);
pliList.add(pli);
}
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("price tracker"),
),
body: Column(
children: [
FutureBuilder<PriceListItem>(
future: pliList, //The argument type 'List<Future<PriceListItem>>' can't be assigned to the parameter type 'Future<PriceListItem>?'.dartargument_type_not_assignable
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: 2,
physics: const ScrollPhysics(),
padding: const EdgeInsets.all(8),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
title: Text(snapshot.data!.price),
subtitle: Text(snapshot.data!.pair),
trailing: const Icon(Icons.currency_bitcoin),
onTap: () {},
),
);
},
);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
)
],
),
);
}
}
CodePudding user response:
Do it like this this:
FutureBuilder<List<PriceListItem>>(
future: Future.wait(pliList),
builder: (context, snapshot) {
}