I have a StreamProvider here:
final secondTabProvider = StreamProvider((ref){
EmergencyContactsController contacts = EmergencyContactsController(currentUserID: ref.read(authProvider).currentUser!.uid);
return contacts.getUserEmergencyContacts();
});
And I call it in my build method like so:
_secondTab.when(
data: (data) {
if (!data.exists){
return Text("no data")
}
Map<String, dynamic doc = data.doc() as Map<String, dynamic>;
List conversations = doc['conversation'];
// Store the user profiles
List<EmergencyContactModel> users = [];
for (Map<String, dynamic> user in userConversations){
contacts.getContactInfo(
uid: user['userID']
).then((value){
if (value != null){
EmergencyContactModel contact = EmergencyContactModel.fromJson(value);
contact.messageID = value["id"] + ref.read(authProvider).currentUser!.uid;
users.add(contact);
}
});
}
return Listview.builder(
itemCount: users.length,
itemBuilder: (BuildContext context, int index) => Text(users[index]['name'])
);
},
error: (err, _){
return Text("Error")
},
loading: () => CircularProgressIndicator()
)
The contacts.getContactInfo() method is an async and I need it to execute before the loop continues to the next iteration, but it's not doing that. Any help would be largely appreciated.
I solved it. I converted the for loop into its own async function as seen below:
// Generate a list of users that the current user has had conversations with
userinfoGenerator(List userIDs) async {
// Get the user profiles
List<EmergencyContactModel> users = [];
for (Map<String, dynamic> user in userIDs){
Map<String, dynamic>? contactInfo = await contacts.getContactInfo(uid: user['userID']);
if (contactInfo != null){
EmergencyContactModel contact = EmergencyContactModel.fromJson(contactInfo);
contact.messageID = contactInfo["id"] + ref.read(authProvider).currentUser!.uid;
users.add(contact);
}
}
return users;
}
And then I used a Future Builder to return the result of the function as seen below:
return FutureBuilder(
future: userinfoGenerator(userConversations),
builder: (BuildContext context, AsyncSnapshot snapshot){
// Checking if future is resolved
if (snapshot.connectionState == ConnectionState.done) {
// If we got an error
if (snapshot.hasError) {
return Center(
child: CustomText(
label: '${snapshot.error} occurred',
),
);
// if we got our data
} else if (snapshot.hasData) {
// Extracting data from snapshot object
final data = snapshot.data;
return ListView.builder(
shrinkWrap: true,
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
List<String> theName = data[index].name
.split(" ");
return Padding(
padding: const EdgeInsets.only(
top: 12.0),
child: CustomListTile(
contact: data[index],
label: theName.length == 1
? theName[0][0]
: "${theName[0][0]} ${theName[theName
.length - 1][0]}"
),
);
}
);
}
}
return const Center(
child: CircularProgressIndicator(
color: kDefaultBackground,
),
);
},
);