john
john

Reputation: 19

Is there a way to return a certain value before it goes out of scope for dart/flutter?

Thank you for taking a look at my question. Here is what I have so far.

List test() {
// ignore: deprecated_member_use
List<String> newList = [];

FirebaseFirestore.instance
    .collection('userInput/xCj26wS73dslrIXsggrY/userInput2')
    .snapshots()
    .listen((event) {

  event.docs.forEach((docs) {
  
    newList.add(docs['Weight'].toString());
    print('1\n');
    print(newList);//first prints out '0' then '40'
  });
  print('2\n');
  print(newList); //prints out '0 40' this is what i want the value to be
  /**
   * 
   * Is there a way to return here?
   * If i try to 'return newList', i get an error of 'The return type 'List<String>' isn't a 'void', 
   * as required by the closure's context.'
   
   */
 
});
print('3\n');
print(newList);//prints out empty list
return newList;//returns empty list

}

I have tried adding comments to make this a little easier to read/understand. I'm trying to access a certain data in a collection and add that value to a list. The issue I am having is by the time i can use a return statement, the variable loses the value I want it to have. Is there a way to call return under where I have ' print('2\n');'? If not, how can i return my list before it goes out of scope? While looking at other recourses, I came across this, which would print out each of the specific data in the collection; however, I want to add each of the data into a new list.

 Widget build(BuildContext context) {
return Scaffold(
  body: StreamBuilder(
    stream: FirebaseFirestore.instance
        .collection('userInput/xCj26wS73dslrIXsggrY/userInput2')
        .snapshots(),
    builder: (context, AsyncSnapshot<QuerySnapshot> streamSnapshot) {
      return ListView.builder(
        itemCount: streamSnapshot.data?.docs.length,
        itemBuilder: (ctx, index) => Text(streamSnapshot.data?.docs[index]
           ['Exercise']),
           
      );
    },
  ),
 
);

}

I would appreciate any tips, feedback, etc.. Thank you.

Upvotes: 2

Views: 135

Answers (1)

jamesdlin
jamesdlin

Reputation: 90015

return within your listen callback makes no sense; where would the returned value go?

Your test function returns an empty List because it returns immediately without waiting to receive all of the asynchronous events from the stream. Streams are asynchronous; your test function must be asynchronous too. One way to wait:

Future<List<String>> test() async {
  var newList = <String>[];

  await for (var event in FirebaseFirestore.instance
      .collection('userInput/xCj26wS73dslrIXsggrY/userInput2')
      .snapshots()) {
    for (var docs in event.docs) {
      newList.add(docs['Weight'].toString());
    }
  }
  return newList;
}

Or, using collection-for:

Future<List<String>> test() async {
  return [
    await for (var event in FirebaseFirestore.instance
        .collection('userInput/xCj26wS73dslrIXsggrY/userInput2')
        .snapshots())
      for (var docs in event.docs) docs['Weight'].toString(),
  ];
}

Upvotes: 1

Related Questions