Reputation: 355
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,
),
);
}
}
Upvotes: 1
Views: 5178
Reputation: 2738
You don't need FutureBuilder
if you are inside a StatefulWidget
:
@override
void initState() {
xyz().then((value) {
setState(() {
l_orders = value;
});
});
super.initState();
}
Then you can build it like this:
// Scaffold body
body: l_orders == null ?
CircularProgressIndicator() :
Text('l_orders received!')
With FutureBuilder
you don't even need the widget to be StatefulWidget
. I only use StatefulWidget
if I need to call setState
to force it to rebuild. If I never use setState
within a StatefulWidget, then there's no need to keep it stateful.
Upvotes: 0
Reputation: 17143
You're not passing a Future
to FutureBuilder
. l_orders
is actually a String
because you're await
ing 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.
Upvotes: 3