0

I have been learning flutter for 2-3 months now and I feel I have a reached a fundamental roadblock with understanding state management. This post will be long unfortunately so please bare with me and I hope I put the right detail.

Problem Definition I have a list of widgets in a shopping cart,im at the point where I click minus and it only has 1 left the widget must be removed.No matter what I try I cant get that widget to be removed. If I click back button and go back into cart the Item will not appear anymore.

I have considered other methods, like disposing the widget(that didn't seem to work) and I was busy implementing Visibility Show/hide widgets in Flutter programmatically but that doesn't feel like the right way.If my understanding of providers,changeNotifiers,async and future builders,is correct the below method should work and I think its fundamental to my flutter journey to understand why it doesn't work.

Overview:The idea was to use the minus button on CartItemWidget to call a method that updates Json stored on the local device, then repopulate the List cartProdList in ProductProvider which calls notifyListeners() and then should propagate everywhere the provider is used. Now I have used this pattern successfully 5 times now, the only different this time is it will be removing a widget which I haven't done before. But this should work dynamically if the future is based of the same provider right ?

function call order

CartItemWidget.onPressed:()

calls >>>

ProductProvider.cartMinusOne(String id)

calls >>>

ProductProvider.Future<List<Product>> cartProducts()

well here goes the code.I also wouldn't mind comments on things I could be doing better in all areas.

CartWidget


    class CartWidget extends StatefulWidget {
      @override
      _CartWidgetState createState() => _CartWidgetState();
    }
    
    class _CartWidgetState extends State<CartWidget> {
      var providerOfProd;
      ProductProvider cartProdProvider = new ProductProvider();
      @override
      void initState() {
        _productsList = new ProductsList();
        super.initState();
        providerOfProd = Provider.of<ProductProvider>(context, listen: false).cartProducts();
      }
    
      @override
      Widget build(BuildContext context) {

    
    ........
    Column(children: <Widget>[
          FutureBuilder(
                        future: providerOfProd,
                        builder: (context, snapshot) {
                          switch (snapshot.connectionState) {
                            case ConnectionState.waiting:
                              return Container(
                                width: 0,
                                height: 0,
                              );
                            case ConnectionState.done:
                              return ListView.separated(
 ..............
                                },
                                itemBuilder: (context, index) {
                                  return CartItemWidget(
                                    product: cartProdProvider.cartProdList.elementAt(index),
                                    heroTag: 'cart',
                                    quantity: cartProdProvider.cartProdList.elementAt(index).cartqty,
                                    key: UniqueKey(),
                                  );
                                },
                              ); 
    
    .........

CartItemWidget


    class CartItemWidget extends StatefulWidget {
      CartItemWidget({Key key, this.product, this.heroTag, this.quantity = 1}) : super(key: key);
    
      // ProductProvider cartProd = new ProductProvider();
      String heroTag;
      Product product;
      int quantity;
    
      @override
      _CartItemWidgetState createState() => _CartItemWidgetState();
    }
    
    class _CartItemWidgetState extends State<CartItemWidget> {
      @override
      Widget build(BuildContext context) {
        return Consumer<ProductProvider>(
          builder: (context, productProv, _) => InkWell(

            child: Container(
    .............
                child: Row(
                  children: <Widget>[
    .............
                              IconButton(
                                onPressed: () {
                                  setState(() {
                                    productProv.cartMinusOne(widget.product.id);
                                    widget.quantity = this.decrementQuantity(widget.quantity);
                                  });
                                }
    .............

ProductProvider


    class ProductProvider with ChangeNotifier {
      ProductProvider() {
        cartProducts();
      }
    
    List<Product> cartProdList;
    
    cartMinusOne(String id) async {

//Code to minus item,then return as a string to save as local jason

        var test = jsonEncode(cartList);
        saveLocalJson(test, 'cart.json');
        cartProducts();
        notifyListeners();
      }
    
    Future<List<Product>> cartProducts() async {
        String jsonString = await JsonProvider().getProductJson();
        String cartString = await getCartJson();

        var filterProdList = (json.decode(jsonString) as List).map((i) => Product.fromJson(i)).toList();

//code to get match cart list to product list

        cartProdList = filterProdList.where((element) => element.cartqty > 0).toList();
        notifyListeners();
        return cartProdList;
      }
    ........................

  • post the minimal, complete sample code that could be run without any changes / modifications – pskink Oct 09 '20 at 06:42
  • That is really a lot of code. The first things that I noticed is that you create the future for your FutureBuilder inside the build method. Don't do that. The build method can be called for a number of reasons totally outside your control, don't change state directly in the build method (in contrast to changing state in a method you attach to a widget to be called later, that's totally fine). – nvoigt Oct 09 '20 at 07:03
  • sorry guys absolutely right too much code, I trimmed it down but it cant be runnable. nvoigt I had it also inside the Init but the same result – Charl van der Merwe Oct 09 '20 at 07:15

0 Answers0