I would like to display a different icon depending on the HTTP code (200, 400) received during an API call. In the leading of each ListTile, I call the iconExchange function which is asynchronous.
And I get the error: "The argument type 'Future<Widget?>' can't be assigned to the parameter type 'Widget?'."
Small clarification the ListTile are in a variable called 'listParametres'.
class ApiExchangesPage extends StatelessWidget {
final User? user;
final DocumentSnapshot? member;
const ApiExchangesPage({Key? key, required this.user, this.member})
: super(key: key);
@override
Widget build(BuildContext context) {
final listParametres = [
Column(children: [
ListTile(
onTap: () {
print(ftx.titleDatabase);
Navigator.push(context, MaterialPageRoute(builder: (_) {
return ExchangeConnectScreen(user: user, exchange: ftx);
}));
},
leading: iconExchange(ftx),
title: Text(
"FTX",
style: TextStyle(color: Colors.white),
),
trailing: Icon(
Icons.arrow_right,
color: Colors.white,
),
),
ListTile(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return ExchangeConnectScreen(
user: user,
exchange: binance,
);
}));
},
leading: iconExchange(binance),
title: Text(
"Binance Future",
style: TextStyle(color: Colors.white),
),
trailing: Icon(
Icons.arrow_right,
color: Colors.white,
),
),
ListTile(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return ExchangeConnectScreen(
user: user,
exchange: bybit,
);
}));
},
leading: iconExchange(bybit),
title: Text(
"Bybit",
style: TextStyle(color: Colors.white),
),
trailing: Icon(
Icons.arrow_right,
color: Colors.white,
),
),
ListTile(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (_) {
return ExchangeConnectScreen(
user: user,
exchange: bitmex,
);
}));
},
leading: iconExchange(bitmex),
title: Text(
"Bitmex",
style: TextStyle(color: Colors.white),
),
trailing: Icon(
Icons.arrow_right,
color: Colors.white,
),
),
])
];
return Scaffold(
backgroundColor: backgroundColor,
appBar: MyAppBar(
title: "Exchanges",
),
body: ListView.separated(
itemBuilder: (context, index) {
return listParametres[index];
},
separatorBuilder: (context, index) {
return Divider(
color: Colors.white,
);
},
itemCount: listParametres.length),
);
}
Future<int> appelBDD(Exchange exchange) async {
var member = await FirebaseFirestore.instance
.collection('member')
.doc(user?.uid)
.get();
print(member);
if (member.data()![exchange] != null) {
List pa = await member.data()?[exchange] ?? [""];
int code = await TestApiClass()
.appelApi(exchange, pa[0].toString(), pa[1].toString());
print(code);
return code;
}
return 0;
}
Future<Widget?> iconExchange(Exchange exchange) async {
var appel = await appelBDD(exchange);
print(exchange.titleDatabase);
print(appel);
if (appel == 200) {
return Icon(
Icons.check_circle,
color: Colors.green,
);
} else {
return Icon(
Icons.dangerous_rounded,
color: Colors.red,
);
}
}
}
Thank you in advance for your help.
CodePudding user response:
You should use the dedicated FutureBuilder
widget : https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
This way you will be able to have a different icon :
- when request is being made (loading)
- request fails
- request succeed
Example of use :
FutureBuilder<Album>(
future: futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data!.title);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
},
)