I am having an issue with my code.
Essentially, what I am trying to do is dynamically create cards that display file information, after pulling the data from a sqflite database.
The issue I have is that my ListView
has a return type of <List<Widget>>
and my query from the sqflite DB returns with a <Future<List<Widget>>>
. I know this problem requires a FutureBuilder
, but I am not sure where to implement it.
Here is the error message:
The argument type Future<List< Widget >> can't be assigned to the parameter type List< Widget >
This is the code that pulls the data from the DB, and stores the resulting card widget in the list itemsList
Future<List<Widget>> getRecordedItems() async {
List<Widget> itemsList = [];
final dbHelper helper = dbHelper();
var recordings = await helper.getRecordings();
var len = recordings.length;
for (var i = 0; i < len; i++) {
var id = recordings[i]["id"];
var filepath = recordings[i]["filepath"];
var filelength = recordings[i]["length"];
var loopCode = Card1(filepath, i, len, filelength);
itemsList.add(loopCode);
}
return itemsList;
}
This is my current return
statement:
var items = getRecordedItems();
return ListView(children: items);
This is the code that is receiving the ListView
object in another file:
Widget build(BuildContext context) {
final AudioPlayerController audioController =
Provider.of<AudioPlayerController>(context);
return Scaffold(
backgroundColor: AppColor.AppBackgroundColor,
appBar: const PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight), child: Titlebar()),
body: Container(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(children: [
const PastRecordingsHeader(name: "$name"),
const Spacer(
flex: 1,
),
SizedBox(
height: MediaQuery.of(context).size.height /1.67,
child: RecordingCard(name: '$name')
)
]),
)),
bottomNavigationBar: PrevRecordingsNavBar();
RecordingCard()
is where the <List<Widget>>
is called.
Can someone please help me understand where to place the FutureBuilder?
Tried implementing the FutureBuilder
outside the ListView
, and inside the ListView
to no avail.
To fetch your data right, you need to put a (FutureBuilder) Widget above (ListView) Widget that you already have, and in this case, the list will not be implemented until the data comes, so to check if the data comes or not you need to make (if statement) as you see below to show other Widget until the data comes, and after the function completed then your list will show the fetched data from the function.
FutureBuilder<List<Widget>>(
future: getRecordedItems(),
builder: (context, data) {
if (data.hasData) {
List<Widget> dataList = data.data!;
return ListView(children: dataList);
} else {
Text(
'There is no data'); // put any widget you want in case there is no data
}
}),