Reputation: 541
I'm making an app where I want to show a progress indicator before the API returns some data. If there is any data on the API call then I want to show Widget-A or else Widget-B. But I'm not sure how to show Widget-B.
I'm only able to do the following so far...
list!.isNotEmpty
? ListView.builder(
itemCount: list!["filtered"]["data"].length,
itemBuilder: (_, index) {
return ListTile(
title: Text(
'${list!["filtered"]["data"][index]["strikePrice"]}'),
);
},
)
: LinearProgressIndicator(),
);
Here ListView.builder()
is Widget-A and a button would be Widget-B, which IDK how to show if list is empty.
Can you help me achieve this? TIA.
Upvotes: 1
Views: 1163
Reputation: 600
You could track if it's loading or not like this:
class _NiftyScreenState extends State<NiftyScreen> {
Map<String, dynamic>? niftyDetails = {};
late bool isLoading;
@override
void initState() {
super.initState();
getNiftyDetails();
}
getNiftyDetails() async {
setState(() {
isLoading = true;
});
try {
this.niftyDetails = await fetchNiftyData();
catch (err) {
print(err);
// Here you can save the error message if you want to show it
}
setState(() {
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading
? LinearProgressIndicator()
: niftyDetails!.isNotEmpty
? ListView.builder(
itemCount: niftyDetails!["filtered"]["data"].length,
itemBuilder: (_, index) {
return ListTile(
title: Text(
'${niftyDetails!["filtered"]["data"][index]["strikePrice"]}'),
);
},
)
: WidgetB(),
);
}
}
Upvotes: 2
Reputation: 458
Take a boolean variable, let's say bool _isLoading;
Just before you trigger your API call set it to true setState(() { _isLoading = true });
,
then as soon as you receive response from your API set the boolean value to false setState(() { _isLoading = false});
.
Lastly,
!_isLoading?
list!.isNotEmpty
? ListView.builder(
itemCount: list!["filtered"]["data"].length,
itemBuilder: (_, index) {
return ListTile(
title: Text(
'${list!["filtered"]["data"][index]["strikePrice"]}'),
);
},
)
: Container(
child: Text("list is empty"), // show whatever you'd like to when list is empty
)
: LinearProgressIndicator(),
);
Upvotes: 1
Reputation: 95
One way of doing is by setting a variable before the condition.
Widget widgetToShow = (some condition) ? widgetA : WidgetB;
list!.isNotEmpty ? widgetToShow : LinearProgressIndicator(), );
or just use one variable for everything, using IF of CASE statements to handle 3 possible widgets(A, B and ProgressIndicator).
Upvotes: 0
Reputation: 1117
Or you could use a layout builder
list!.isNotEmpty
? LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final remoteList = list!["filtered"]["data"];
if (remoteList.isNotEmpty) {
return ListView.builder(
itemCount: list!["filtered"]["data"].length,
itemBuilder: (_, index) {
return ListTile(
title: Text(
'${list!["filtered"]["data"][index]["strikePrice"]}'),
);
},
);
} else {
return WidgetB();
}
},
),
: LinearProgressIndicator(),
Upvotes: 0