1

I have a list of userIDs and I want to get a value from the database for each user and write it to a new list. But the for loop doesn't wait for the future and throws the error "Unhandled Exception: RangeError (index): Invalid value: Valid value range is empty: 0"

List userIDs = ["gsdgsgsgda32", "gwerszhgda7h", "fsdgz675ehds"]; Future <dynamic> getList() async { List items=[]; for (var i = 0; i < userIDs.length; i++) { items[i] = await getUserItems(userIDs[i]); } return items; } Future <String?> getUserItems(String? _userID) async { String? userItem=" "; final FirebaseApp testApp = Firebase.app(); final FirebaseDatabase database = FirebaseDatabase.instanceFor(app: testApp); database.ref().child('users').child(_userID!).once().then((pdata) { userItem = pdata.snapshot.child('item').value as String?; }); return userItem; } 

3 Answers 3

2

This is not problem with future. List items is empty so when you call items[0] = 3; there is no items[0] and you get RangeError. Proper way to add element to list is call items.add(3)

So your code should look like this:

List userIDs = ["gsdgsgsgda32", "gwerszhgda7h", "fsdgz675ehds"]; Future <dynamic> getList() async { List items=[]; for (var i = 0; i < userIDs.length; i++) { final item = await getUserItems(userIDs[i]); items.add(item); } return items; } Future <String?> getUserItems(String? _userID) async { String? userItem=" "; final FirebaseApp testApp = Firebase.app(); final FirebaseDatabase database = FirebaseDatabase.instanceFor(app: testApp); database.ref().child('users').child(_userID!).once().then((pdata) { userItem = pdata.snapshot.child('item').value as String?; }); return userItem; } 
Sign up to request clarification or add additional context in comments.

Comments

0

By using .then you are telling dart to continue running and come back when the Future completes. Instead you should use await inside getUserItems.

You have to fiddle around a bit but here's a suggestion to start with:

Future <String?> getUserItems(String? _userID) async { String? userItem=" "; final FirebaseApp testApp = Firebase.app(); final FirebaseDatabase database = FirebaseDatabase.instanceFor(app: testApp); userItem = (await database.ref().child('users').child(_userID!).once()).snapshot.child('item').value as String? return userItem; } 

Also using String? for userItem and setting it to " " is a bit of an anti pattern. Since you allow it to be nullable i'd suggest having it as null writing your logic around that.

Comments

-1

Try to use it like this

 Future <dynamic> getList() async { List items=[]; userIDs.forEach((item) async { items.add(await getUserItems(item)); }); return items; } 

3 Comments

No - use of forEach here is incorrect. Use the for loop in @corvus answer.
okay, I got that. Thnx for the clarification.@jamesdlin

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.