Reputation: 463
i am trying to use bloc pattern in flutter application i write the code inside body of build function before return Scaffold(); as following
@override
Widget build(BuildContext context) {
final ProductsController pController = Provider.of<ProductsController>(context);
pController.addProducts();
return Scaffold();
}
every thing is perfect but the function addPrducts() calls too many times it looks the following code repeat it self many times
pController.addProducts();
here is the structure of ProductsContoller class
class ProductsController extends ChangeNotifier {
List<Products> _products=List();
AppDatabase appDB=AppDatabase();
List<Products> get products=>_products;
addProducts() {
appDB.getFromTable(AppDatabase.TBL_PRODUCTS).then((rows){
rows.forEach((row){
Products product=Products.fromJson(row);
_products.add(product);
});
notifyListeners();
});
}
}
Upvotes: 3
Views: 3949
Reputation: 53
you must define your widget that used your list in other classes (stateful or stateless).
for example, if you use List in ListView, you must create a stateless class for your ListView and watch list in this class.
class ProductList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 260,
childAspectRatio: 3 / 4.6,
),
itemCount: context.watch<ProductsController >().productPjo.listProduct.length,
shrinkWrap: true,
itemBuilder: (_, i) {
return ItemProduct(context.watch<ProductsController >().productPjo.listProduct[i]);
},
);
}
}
Upvotes: 0
Reputation: 725
If you want to do some operation like fetching screen data only once in the stateful widget then you can make use of void didChangeDependencies()
along with the boolean flag.
didChangeDependencies() is also called immediately after initState. Also called when a dependency of this State object changes. It is safe to call BuildContext.dependOnInheritedWidgetOfExactType from this method.
final ProductsController pController
var _isLoadingForFirstTime = true;
@override
void initState() {
super.initState();
}
@override
void didChangeDependencies() {
if (_isLoadingForFirstTime) {
pController = Provider.of<ProductsController>(context);
pController.addProducts();
}
_isLoadingForFirstTime = false;
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
return Scaffold(); // You Screen contents here
}
Upvotes: 1
Reputation: 139
If your function should only get called once u should try to override the initState()
Method and call it there. If your class extends a StatefulWidget
your build(BuildContext context)
Method possibly gets called multiple times.
final ProductsController pController
@override
void initState() {
pController = Provider.of<ProductsController>(context);
pController.addProducts();
super.initState();
}
Upvotes: 1