1

I am trying to show the price of items in the cart but the total value should be shown in TextField. I am saving data to SQLite and retrieving then show to a widget, but when I try to access total_price to another widget it's not updating, but When I press hot reload again the data shows but not first time when I am opening the page

  return FutureBuilder<List<CartModel>>(
      future: fetchCartFromDatabase(),
      builder: (context, snapshot) {

        if (snapshot.hasData && snapshot.data.length > 0) {
           cartCount = snapshot.data.length;
           for(int i = 0;i<snapshot.data.length;i++){
            var price = snapshot.data[i].product_price.split("₹");
            total_price+=double.parse(price[1]);
          }
  } else if (snapshot.hasData && snapshot.data.length == 0) {
          return new Text("No Data found");
        }
        else
          {
            return new Container(
              alignment: AlignmentDirectional.center,
              child: new CircularProgressIndicator(),
            );
          }
);

value initialized

  int cartCount = 0;
  double total_price=0.0;

1 Answer 1

3

The FutureBuilder updates only its children. To update the value of another widget you must use setState.

The best way would be putting FutureBuilder in an upper level or using some sort of state manager, like provider.

To use setState you need to initialize you fetch from an initState of a stetefullWidget (or to call it from a function). This way you will not need a FutureBuilder and must refactor your code:

class YourWidget extends StatefulWidget {
  @override
  _YourWidgetState createState() => _YourWidgetState();
}

class _YourWidgetState extends State<YourWidget> {
  double total_price = 0;

  @override
  void initState() {
    super.initState();
    fetchCartFromDatabase().then((value){
      setState((){
        for(int i = 0;i<value.length;i++){
          var price = value[i].product_price.split("₹");
          total_price+=double.parse(price[1]);
        } 
      });
    });
  }
}

The addPostFrameCallback is not a good solution, since it updates the value only in the next frame. When the app grows it leads to lags.

To continue using the FutureBuilder, move your widget tree that needs to be updated to be inside of the FutureBuilder.

Sign up to request clarification or add additional context in comments.

6 Comments

setState doesn't work i tried,when you use seState inside widget this setState() or markNeedsBuild() called during build. error will throw @racr0x
so i searched the error i got then i findout WidgetsBinding.instance.addPostFrameCallback((_){}); with this i can use setState with in widget but when i use this it increment the price without stoping, @racr0x
I thought it wouldn't but didn't test. I will update with a proper solution.
brother i got it but it not clean way i think,this page contains two widgets,so i have merged the second widget to first widget with future builder now it works,it's not good way i think @racr0x
There are many ways to do what you want: using streams (see bloc pattern), provider, inherited widgets, all of them managing states and updating the widget tree. Using FutureBuilder with big widget trees inside is not the best option but with smaller ones there is no problem.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.