'Work with nested Futurebuilders in one widget
I am calling two futures in one ListViewbuilder to display my data , I want to be able to use two nested future builders (I can't use future.await because each future has a different return type)
For now the second future builder is causing a null error (my service works just fine)
what seems to be the problem ?
myList = myQrqcListViewModel.articlesList;
List<Qrqc>? qrqcList = myList;
Future<List<Qrqc>>? _fetch(int count) {
return Future.delayed(
Duration(seconds: 1),
() => qrqcList!.take(count).toList(),
);
}
_controller.addListener(() {
var triggerFetchMoreSize =
0.5 * _controller.position.maxScrollExtent;
if (_controller.position.pixels > triggerFetchMoreSize ) {
setState(() {
isBottom = true;
});
if(qrqcList!.length == _count ){
setState(() {
_count += 8;
});
}
print(_count);
}else{
setState(() {
isBottom = false;
});
}
print (isBottom);
});
QrqcDetails? result;
String ? type;
return FutureBuilder(
future: _fetch(_count),
builder: (BuildContext context, AsyncSnapshot <List<Qrqc>>? snapshot){
if(snapshot!.hasData){
String? backgroundImage;
return ScrollListener(
threshold: 0.8,
builder: (context,controller){
final listView = ListView.builder(
controller: _controller ,
physics: const AlwaysScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: qrqcList!.length,
itemBuilder: (BuildContext context, int index) {
futureQrqc = QrqcDetailViewModel().fetchQrqcDetail(qrqcList[index].id);
return FutureBuilder(
future: futureQrqc,
builder: (BuildContext context,
AsyncSnapshot<QrqcDetails?> snapshot){
String? backgroundImage;
String? _setImage() {
String _mTitle = "${snapshot.data!.type}";
if(_mTitle == null){
backgroundImage = "assets/icons/delivery.png";
}
else if(_mTitle == "Delivery") {
backgroundImage = "assets/icons/delivery.png";
} else if(_mTitle == "Security") {
backgroundImage = "assets/icons/security.png";
}
else if(_mTitle == "Quality") {
backgroundImage = "assets/icons/quality.png";
}
else if(_mTitle == "Cost") {
backgroundImage = "assets/icons/Cost.png";
}
else if(_mTitle == "People") {
backgroundImage = "assets/icons/people.png";
}
print("_mTitle: $_mTitle");
print("_mTitle: $backgroundImage");
return backgroundImage; // here it returns your _backgroundImage value
}
if (snapshot.hasData){
Column(
children: [
ConditionalBuilder(condition:qrqcList[index].status == 'INIT', builder: (context) => QrqcBody(
child: QrqcCard(child:QrqcCardBody(
color: Colors.orange,
text: qrqcList[index].status,
leading: QrqcCardLeaing(imgPath: _setImage()),
trailing: QrqcCardtrailing(text:qrqcList[index].progress.toString(),percent: qrqcList[index].progress.toString(),),
title: qrqcList[index].id.toString(),
subtitle: qrqcList[index].title,
chlidren: [
QrqcDetailsCardFirstRow(
product: snapshot.data?.product?? "No product" ,
role: qrqcList[index].role?? "no role",
),
const SizedBox(height: 10),
QrqcDetailsCardSecondRow(
perim: snapshot.data?.product?? "no perim",
date: convertDateTimeDisplay(snapshot.data!.creation_date??"no date"),
),
const SizedBox(height: 10),
],
)),
),
fallback: null),
ConditionalBuilder(condition:qrqcList[index].status == 'SUBMITTED', builder: (context) => QrqcBody(
child: QrqcCard(child:QrqcCardBody(
color: Colors.blueAccent,
text: 'SUB',
leading: QrqcCardLeaing(imgPath: _setImage()),
trailing: QrqcCardtrailing(text:qrqcList[index].progress.toString(),percent: qrqcList[index].progress.toString(),),
title: qrqcList[index].id.toString(),
subtitle: qrqcList[index].title,
chlidren: [
QrqcDetailsCardFirstRow(
product: snapshot.data?.product?? "No product" ,
role: qrqcList[index].role?? "no role",
),
const SizedBox(height: 10),
QrqcDetailsCardSecondRow(
perim: snapshot.data?.product?? "no perim",
date: convertDateTimeDisplay(snapshot.data!.creation_date??"no date"),
),
const SizedBox(height: 10),
],
)),
), fallback: null),
ConditionalBuilder(condition:qrqcList[index].status == 'ESCALATED', builder: (context) => QrqcBody(
child: QrqcCard(child:QrqcCardBody(
color: Colors.red,
text: 'ESCAL',
leading: QrqcCardLeaing(imgPath: _setImage()),
trailing: QrqcCardtrailing(text:qrqcList[index].progress.toString(),percent: qrqcList[index].progress.toString(),),
title: qrqcList[index].id.toString(),
subtitle: qrqcList[index].title,
chlidren: [
QrqcDetailsCardFirstRow(
product: snapshot.data?.product?? "No product" ,
role: qrqcList[index].role?? "no role",
),
const SizedBox(height: 10),
QrqcDetailsCardSecondRow(
perim: snapshot.data?.product?? "no perim",
date: convertDateTimeDisplay(snapshot.data!.creation_date??"no date"),
),
const SizedBox(height: 10),
],
)),
), fallback: null)
],
);
}else if(snapshot.hasError){
return const NoDataUI();
}
return Text(snapshot.error.toString());
}
);
}
);
return Stack(
children: [
listView,
ConditionalBuilder(condition: isBottom == true ,
builder: (context) =>Positioned(
left: 100,
right: 100,
bottom: 0,
child: Container(
width: 80,
height: 80,
child: Center(child: CircularProgressIndicator()),
),
),
fallback: null)
],
);
},
loadNext: () {
if (qrqcList!.length == _count ) {
setState(() {
_count += 8;
});
}
print (_count);
},
);
}else if (snapshot.hasError){
return NoDataUI();
}
return Center(
child: CircularProgressIndicator(),
);
}
);
I need both futures to return the same widget .If anyone can help solve the issue or know another way to call my futures please don't hesitate to help thank you so much.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
