I have a project where I call a Future ( initProducts()
) that gets a list for a Provider
at the beginning of the application (when creating the Provider
in the Main
). I then use this list repeatedly in my project on different pages, so I have to check that the Future has already been completed.
Every time I check if the Future has already been completed, should I do it with a FutureBuilder
even if the Future has already been called before or should I simply use a if
and have it NotifyListeners()
redraw the Widget later?
Here I show it for better understanding:
Where do I call initProducts()
:
void main() async{
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ProductProvider()..initProducts()),
],
child: MyApp(),
),
);
}
initProducts() itself (check that it hasn't already been completed earlier):
Future<List<Product>> initProducts()async{
if(_products.isEmpty){
_products = await ProductsDatabaseService.readProducts() ?? []; //se rellena la lista que necesito posteriormente
notifyListeners();
}
return _products;
}
When I subsequently use the data obtained with initProducts(), which of these is the correct way?
Form 1:
return FutureBuilder(
future: productProvider.initProducts(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if(snapshot.hasData){
//código que se realiza si ya se ha completado el Future
}else{
return CircularProgressIndicator();
}
},
);
Form 2:
if(productProvider.products.isNotEmpty){
return ListView.builder(
itemCount:productProvider.products.length,
itemBuilder://Widget que devolverá en base a la lista obtenida por el Future
);
}else{
return CircularProgressIndicator();
}
Way 2 is the most optimal, if you already use a state manager and you have your bloc/notifier/provider that indicates that it should repaint (
notifyListeners
), and you also have a widget that listens for changes, it is no longer necessary to use theFutureBuilder
, it is okay plus.With this you avoid not only one less widget in the tree, but also, unnecessary calls
productProvider.initProducts()
to perform validation, you save CPU cycles (almost not felt).