Mokhtar Ghaleb
Mokhtar Ghaleb

Reputation: 463

Flutter bloc pattern repeat calling function many times

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

Answers (3)

mahan
mahan

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

Ameer
Ameer

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

tbs
tbs

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

Related Questions