Reputation: 143
im trying to return two futures and getting the above error when trying to access the data within the returned snapshot.Specifically this line:
${snapshot.data!["firstName"]}
Any ideas as to the correct way to access this data, can't see any documentation anywhere defining this.
Code is as follows:
Widget build(BuildContext context) {
return FutureBuilder(
future: Future.wait([getData(), getMood()]),
builder: (_, snapshot) {
if (snapshot.hasData) {
return Scaffold(
appBar: AppBar(
title: const Text('Display the Picture'),
backgroundColor: kPrimaryColor,
),
// The image is stored as a file on the device. Use the `Image.file`
// constructor with the given path to display the image.
body: Center(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(8.0, 20.0, 8.0, 8.0),
child: Column(
children: [
Center(
child: Text(
"${snapshot.data!["firstName"]} \n\n "
"We have predicted your mood as:\n\n "
"${snapshot.data!.data()!["mood"]}\n\n"
"Please select a reason associated to your mood",
style: const TextStyle(
color: Colors.black, fontSize: 15),
textAlign: TextAlign.center,
),
),
],
),
),
],
),
),
);
} else {
return CircularProgressIndicator();
}
},
);
}
Future getData() async {
var currentUser = FirebaseAuth.instance.currentUser;
DocumentSnapshot q1 = await FirebaseFirestore.instance
.collection('USER_TABLE')
.doc(currentUser!.uid)
.get();
return q1;
}
Future getMood() async {
var currentUser = FirebaseAuth.instance.currentUser;
QuerySnapshot q2 = await FirebaseFirestore.instance
.collection('userMood')
.where('userId' == currentUser!.uid)
.orderBy('createdAt',descending: true)
.limit(1)
.get();
return q2;
}
}
Thanks
EDIT
future: Future.wait([getData(), getMood()]),
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
if (snapshot.hasData) {
var a = snapshot.data![0]["firstName"] as String;
var b = snapshot.data![1]['Prediction'] as String;
Future <String> getData() async {
var currentUser = FirebaseAuth.instance.currentUser;
DocumentSnapshot q1 = await FirebaseFirestore.instance
.collection('USER_TABLE')
.doc(currentUser!.uid)
.get();
return q1.toString();
}
Future <String> getMood() async {
var currentUser = FirebaseAuth.instance.currentUser;
QuerySnapshot q2 = await FirebaseFirestore.instance
.collection('userMood')
.where('userId' == currentUser!.uid)
.orderBy('createdAt',descending: true)
.limit(1)
.get();
return q2.toString();
}
Upvotes: 1
Views: 108
Reputation: 5876
Let's simplify the task:
Future getA() async {
await Future.delayed(Duration(seconds: 1));
return 12.34;
}
Future getB() async {
await Future.delayed(Duration(seconds: 1));
return 'abc';
}
... FutureBuilder(
future: Future.wait([getA(), getB()]),
builder: (context, snapshot) {
if (snapshot.hasData) {
// how to get a and b from snapshot?
} else {
return CircularProgressIndicator();
}
},
)
You're trying to do snapshot.data!['a']
and snapshot.data!['b']
. It doesn't work because snapshot.data
isn't Map<String, something>
.
Future.wait
returns Future<List<T>>
. So snapshot.data
will be List<T>
, and you can get individual items like snapshot.data![0]
and snapshot.data![1]
.
Another problem is that Future.wait
doesn't support different item types, so the items type will be Object
and you'll need to cast it manually.
Future<double> getA() async {
await Future.delayed(Duration(seconds: 1));
return 12.34;
}
Future<String> getB() async {
await Future.delayed(Duration(seconds: 1));
return 'abc';
}
... FutureBuilder<List<Object>>(
future: Future.wait([getA(), getB()]),
builder: (context, snapshot) {
if (snapshot.hasData) {
var a = snapshot.data![0] as double;
var b = snapshot.data![1] as String;
return Text('$a $b');
} else {
return CircularProgressIndicator();
}
},
)
Upvotes: 1