Akshay
Akshay

Reputation: 95

Flutter - Dart - setState does not reload state when using with Future<> for the async function

I have a Flutter code with setState() for the RaisedButton, working fine to change all the local variables like changing button color, hide/show other components on the same page etc. But when I use Future statusCode = myFun(); where myFun() is Async function, Future always returns code properly by setState() takes effect every 2nd time.

My code is here:

return RaisedButton(
    color: infBtnColor ? Colors.green : Colors.grey,
    textColor: Colors.black87,
    onPressed: () {
      setState(() {

        infBtnColor = true;    //this takes effect on click properly -always

        Future<int> statusCode = myFun(false);
        statusCode.then((value) {

          if (value == 200) {
            ESPSyncIconColor = true;   // this is to modify other icon from the AppBar
            print("Btn GREEN");
          }
          else {
            ESPSyncIconColor = false;
            print("RED");
          }
        });
      });

    }
);

And the App bar code is here:

AppBar(

    title: Text(title,style: TextStyle(fontSize:18,fontWeight: FontWeight.w300,)),
    backgroundColor: new Color(0xff303030),

    actions: <Widget>[
    Padding(
    padding: EdgeInsets.only(right: 25.0),
    child: Row(
    children: <Widget>[

    Icon(Icons.cloud_upload,size: 26,
    color: (**ESPSyncIconColor**)?Colors.green:Colors.red,

    ),],),),
    ],),

Here I am using variable ESPSyncIconColor to update Icon color from the AppBar of the same page. Which always work on second time, that too with the previous status.

Upvotes: 3

Views: 2791

Answers (4)

Akshay
Akshay

Reputation: 95

All the answers above helped me fixing this issue:

My modified code is here, just in case anyone else faces this issue.

Future<int> statusCode = myFun(true);
        statusCode.then((int value) {
          setState(() {
            if (value == 200) {
              ESPSyncIconColor = true;
              print("Time Btn GREEN");
            }
            else {
              ESPSyncIconColor = false;
              print("Time Btn RED");

            }
            print(value);
          });

Upvotes: 0

Abion47
Abion47

Reputation: 24781

You are calling a future inside setState. This future isn't going to complete until after setState returns and the widget is rebuilt. Instead, await or then the future and call setState afterward.

onPressed: () {
  infBtnColor = true;
  myFun(false).then((value) {
    setState(() {
      if (value == 200) {
        ESPSyncIconColor = true;   // this is to modify other icon from the AppBar
        print("Btn GREEN");
      } else {
        ESPSyncIconColor = false;
        print("RED");
      }
    });
  });
}

Upvotes: 1

Patrick
Patrick

Reputation: 3759

You must call setState again for the other variable change:

myFun(false).then((value) => setState(() => ESPSyncIconColor = value == 200));

Upvotes: 0

Adarsh Balu
Adarsh Balu

Reputation: 352

Do not use setState with Future functions. Set the state after the future executes. Await and later use setState().

     onPressed: () {
    
            infBtnColor = true;    //this takes effect on click properly -always
    
            Future<int> statusCode = myFun(false);
          await statusCode.then((value) {
    
              if (value == 200) {
                ESPSyncIconColor = true;   // this is to modify other icon from the AppBar
                print("Btn GREEN");
              }
              else {
                ESPSyncIconColor = false;
                print("RED");
              }
            });
          
    setState((){

});
        }

Upvotes: 0

Related Questions