Reputation: 393
I am new at Flutter so I am sorry if this problem seems trivial or irrelevant!
I have created another class for getting and setting data, Repository
, as I use Cloud Firestore, the data I want for this specific question is stored in a collection, so I get all the documents in the collection as a QuerySnapshot
and then add all the documents in a List<DocumentSnapshot>
.
Here is the method:
Future<List<DocumentSnapshot>> getCollection(CollectionReference colRef) async {
List<DocumentSnapshot> dummyList = new List();
await colRef.getDocuments().then((value) {
dummyList.addAll(value.documents);
});
return dummyList;
}
Repository:
CollectionReference memoriesColRef =
_firestore
.collection("username")
.document("memories")
.collection("allMem");
List<DocumentSnapshot> documentList = new List();
await getCollection(memoriesColRef).then((value) {
documentList.addAll(value);
});
After all this, I have set up a method in my UI class, to call this Repository
, and it works perfectly there bet when I call it in the build
function, the global list I have passed to access the data, is not able to add the values in it
UI Class
build(...) {
getMemories().then((value) {
print("value size: " + value.length.toString()); // 1
memoriesListMap.addAll(value); // global variable
});
print("valSize: " + memoriesListMap.length.toString()); // 0
print("val: " + memoriesListMap[0]["title"]); // error line
}
Future<List<Map<String, dynamic>>> getMemories() async{
List<Map<String, dynamic>> dummyListMap = new List();
await MemoryOper().getMemories().then((value) {
print("memVal: " + value[0]["title"]); // appropriate value
dummyListMap.addAll(value);
});
return dummyListMap;
}
ERROR
RangeError (index): Invalid value: Valid value range is empty: 0
\
I don't know what's causing this, but please help me out! Thank you
EDIT:
ListView.builder(
itemBuilder: (BuildContext context, int index) {
String title = memoriesListMap[index]["title"]; // error prone line
int remind = memoriesListMap[index]["remind"];
String link = memoriesListMap[index]["link"];
Upvotes: 0
Views: 162
Reputation: 1494
I addition to what nvoigt has said, This article will help you to understand how to implement the Future Builder, in your specific case you can do something like:
build(...){
..
body: getMemories(),
..
}
Widget getMemories() {
return FutureBuilder(
builder: (context, projectSnap) {
if (projectSnap.connectionState == ConnectionState.none &&
projectSnap.hasData == null) {
return Container();
}
return ListView.builder(
itemCount: projectSnap.data.length,
itemBuilder: (context, index) {
ProjectModel project = projectSnap.data[index];
return Column(
children: <Widget>[
// Widget to display the list of project
],
);
},
);
},
future: getCollection(), //this is the important part where you get the data from your Future
);
}
Upvotes: 1
Reputation: 4894
I think you are accessing the element before it gets added since it is async
method.
Try something like this,
build(...) {
getMemories().then((value) {
print("value size: " + value.length.toString()); // 1
memoriesListMap.addAll(value); // global variable
print("valSize: " + memoriesListMap.length.toString()); // 0
print("val: " + memoriesListMap[0]["title"]);
});
}
Hope it works!
Upvotes: 0