Reputation: 757
I have page contain future builder to get username from shared preference :
Widget build(BuildContext context) {
return Consumer<ProductProvider>(builder: (context, prod, child) {
return FutureBuilder(
future: Services().get_user(),
builder: (context, snapshot) {
if (snapshot.hasData) {
var name = snapshot.data['name'];
return OrderDetails(name);
} else {
return Container();
}
});
});
}
that page have widget contain another future builder depend on name value passed through page :
class OrderDetails extends StatelessWidget {
final name;
const OrderDetails(this.name);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: Services().get_orders(name),
builder: (context, snapshot) {
if (snapshot.data != null) {
print('snapshot.data.length ${snapshot.data.length}'); // ------ it is print 6
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Text('user_id');
},
);
} else {
return Container();
}
},
);
}
Services().get_orders(name) method :
get_orders(name) async {
var url = 'http://10.0.2.2:8000/api/user/myorder/$name';
var response = await http.get(url);
var data = jsonDecode(response.body);
return (data);
}
I put data on database which is just this:
{
"id": 3,
"user_id": 24,
"status": "ordered",
"order_item": [
{
"id": 11,
"order_id": 3,
"product_id": 1,
"quantity": 2,
},
{
"id": 12,
"order_id": 3,
"product_id": 2,
"quantity": 1,
}
]
}
Upvotes: 3
Views: 1137
Reputation: 489
because it is used inside the build() method. That's not a problem...if you do not evaluate the Future method inside that. I mean, you should not do this:
Widget build(BuildContext context) {
return FutureBuilder(
future: Services().get_orders(name),
builder: (context, snapshot) {
.....
but this:
Widget build(BuildContext context) {
return FutureBuilder(
future: _myFuture,
builder: (context, snapshot) {
.....
Where _myFuture is evaluated at initState():
class OrderDetails extends StatefullWidget {
@override
_OrderDetailsState createState() => _OrderDetailsState();
}
class _OrderDetailsState extends State<OrderDetails> {
final name;
Future _myFuture;
@override
void initState() {
name = widget.name;
_myFuture = Services().get_orders(name); //this method is async, thus do not slow down the init state: the result is still not ready.
super.initState();
}
const OrderDetails(this.name);
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _myFuture, //the FutureBuilder will wait until the _myFuture will get the results from Services().get_orders(...)
builder: (context, snapshot) {
if (snapshot.hasFinished ) { //better test: data is always not null. at least with zero data.
print('snapshot.data.length ${snapshot.data.length}'); // ------ it is print 6
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Text('user_id');
},
);
} else {
return CircularProgressIndicator(); // a circular progress indicator is the quickest way to tell the user we are waiting for data.
}
},
);
}
Upvotes: 3