I am using the provider package for flutter. https://pub.dev/packages/provider
On Appstart, I use the following provider:
late Future<List<Art>> art;
late Future<List<Music>> music;
late Future<List<Furniture>> furniture;
late Future<List<Clothing>> clothing;
late Future<List<Flower>> flowers;
late Future<List<Interieur>> interieur;
late Future<List<Collectible>> allCollectibles;
@override
void initState() {
super.initState();
art = getAllArts();
music = getAllMusic();
furniture = getAllFurniture();
clothing = getAllClothing();
flowers = getAllFlowers();
interieur = getAllInterieur();
allCollectibles = () async {
return [
...await art,
...await music,
...await furniture,
...await clothing,
...await flowers,
...await interieur,
];
}();
}
@override
Widget build(BuildContext context) {
timeDilation = 1;
return FutureBuilder(
future: settings,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return Center(child: CircularProgressIndicator());
}
return FutureProvider<List<Collectible>>(
create: (context) => allCollectibles, initialData: [],
),});
later on, I use this consumer to retreive it:
@override
Widget build(BuildContext context) {
return Consumer<List<Collectible>>(builder: (context, collectibles, child) {
return sendCollectibleDataFull(collectibles),
});
}
The list in the Method sendCollectibleDataFull
is sometimes there and sometimes not.
If it is empty on call, it will stay empty.
I have updated to nullsafety hence the initialData: [],
got mandatory. Before that, I always got a list from this.
Can I tell my Consumer/Provider to await the data before I retreive it?
Hi @lellek and welcome.
Okay there are a couple of things I want to point out.
You're using the default FutureProvider
constructor with a create callback but in fact you're providing a value that already exists.
return FutureProvider<List<Collectible>>(
create: (context) => allCollectibles, initialData: [],
),});
If you already have a value and you're not creating it with the Provider, you should use the .value
constructor.
However, you could use the default constructor with the create
callback and do all the work there instead of having this StatefulWidget
doing some of the work (unless you just need these instances here as well).
This is not tested but it should look something like this:
FutureProvider<List<Collectible>>(
create: (context) async {
/// get collectibles in parallel
final List<List<Collectible>> results = await Future.wait([
getAllArts(),
getAllMusic(),
getAllFurniture(),
getAllClothing(),
getAllFlowers(),
getAllInterieur(),
]);
/// flatten the results
final allCollectables = [for (final collectibles in results) ...collectibles];
return allCollectables;
},
initialData: [],
)
Can I tell my Consumer/Provider to await the data before I retreive it?
No, the point is that the initial value, in this case []
, will be available from the provider and the tree will update when the future is resolved.