How to use InitState when using Future Function and Future builder in flutter

Issue

I am facing a problem in Flutter. I am not use to using Future Functions that efficiently.
I am trying to get a value from Future function in InitSate of stateful class and later using the return value in Future Builder.
However, at the moment when i do l_orders = await xyz(); or l_orders = xyz(); inside initstate it does not work My screen does not load its always shows only CircularProgressIndicator.

However, when I move l_orders = xyz(); outside InitState than everything works. I want to do this inside InitState as later I want to use setState aswell. So this is my first step of implementation before moving to setState part.

Any sort of help is highly appreciated. Thank You

my codes are –

class _OrderScreenState extends State<OrderScreen> {

  Future<String> xyz() async{
    return("processing ....");
  }

  @override
  Widget build (BuildContext context) {
    final orders = Provider.of<Orders>(context);
    var l_orders;

    @override
    void initState() async {
      super.initState();
      l_orders = await xyz();
    }


    return WillPopScope(
      onWillPop: () async {
        return false;
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text('Orders'),
          actions: <Widget>[Padding(
            padding: const EdgeInsets.all(8.0),
            //child: IconButton(icon:Icon(Icons.home, size: 30,),onPressed: (){Navigator.of(context).pushNamed(HomePage.routeName);},),
          ),],
        ),
        body: FutureBuilder(
          future: l_orders,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (!snapshot.hasData) {
              // while data is loading:
              return Center(
                child: CircularProgressIndicator(backgroundColor: Colors.red,valueColor: new AlwaysStoppedAnimation<Color>(Colors.blue)),
              );
            } else {
              // data loaded:
             return Text("Test");
            }
          },
        ),

        floatingActionButton: FloatingActionButton(

          onPressed: (){Navigator.of(context).pushNamed(HomePage.routeName);},
          child: Icon(Icons.home,size: 40,),
          //backgroundColor: Colors.green,
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
       ),
    );
  }
} 

Solution

You’re not passing a Future to FutureBuilder. l_orders is actually a String because you’re awaiting it in initState. Do not use await in initState even though static analysis may allow you to.

initState should be the following:

@override
void initState() {
  super.initState();
  l_orders = xyz();
}

Additionally, all of your members and your initState declaration are in build. Move them outside of build into the body of your class.

class _OrderScreenState extends State<OrderScreen> {
  var l_orders;

  @override
  void initState() {
    super.initState();
    l_orders = xyz();
  }

  Future<String> xyz() async{
    return("processing ....");
  }

  @override
  Widget build (BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        return false;
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text('Orders'),
          actions: <Widget>[Padding(
            padding: const EdgeInsets.all(8.0),
            //child: IconButton(icon:Icon(Icons.home, size: 30,),onPressed: (){Navigator.of(context).pushNamed(HomePage.routeName);},),
          ),],
        ),
        body: FutureBuilder(
          future: l_orders,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (!snapshot.hasData) {
              // while data is loading:
              return Center(
                child: CircularProgressIndicator(backgroundColor: Colors.red,valueColor: new AlwaysStoppedAnimation<Color>(Colors.blue)),
              );
            } else {
              // data loaded:
             return Text("Test");
            }
          },
        ),

        floatingActionButton: FloatingActionButton(

          onPressed: (){print('test');},
          child: Icon(Icons.home,size: 40,),
          //backgroundColor: Colors.green,
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
       ),
    );
  }
} 

Giving l_orders a static type would help you find these errors at compile-time. Instead of using the dynamic var l_orders;, use Future l_orders; or Future<String> l_orders;. Additionally, pay attention to all static analysis warning. Just because they’re not errors doesn’t mean they don’t matter.

Answered By – Christopher Moore

Answer Checked By – David Marino (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *