Flutter/Dart - Passing/setting variable outside a

2019-09-02 21:00发布

问题:

I have a simple Flutter application that converts a string value separated by pipe chars...happen to be song names (ie: 'Rudolf|Jingle Bells|White Christmas') into a ListView...with songnames being the ListTiles. Long story as to why I'm doing it this way..please bear with me. I have a Firestore collection called 'sets' and in sets I have a document with a key of SET01. Then in SET01 I have one field called 'songs'...a text field holding songs separated by pipes. I call getSetList() to retrieve the text field from Firestore. I can seem to get the value of 'songs' inside the set01DocRef.get().then((snapshot)....

But I cannot seem to pass that value out of the .then() and back to the function to pass it back to the calling widget.

Any help very much appreciated.

ER

String getSetList () {

String songList = 'Loading.....';
DocumentReference set01DocRef = Firestore.instance.collection('sets').document('SET01');

set01DocRef.get().then((snapshot){
  print('String songList inside .then() before assignment:  ' + songList);     //Wagon Wheel|Her Diamonds|Waterfalls
  print('Snapshot value of songs:  ' + snapshot['songs']);         //Wagon Wheel|Her Diamonds|Waterfalls
  songList = snapshot['songs'];     
  print('String songList inside .then() after assignment:  ' + songList);     //Wagon Wheel|Her Diamonds|Waterfalls
});

print('Bueller? Bueller??');
print('String songList outside of .then():  ' + songList);                  

return songList;
}

Output:

flutter: Bueller? Bueller??
flutter: String songList outside of .then():  Loading.....
Reloaded 0 of 424 libraries in 442ms.
flutter: String songList inside .then() before assignment:  Loading.....
flutter: Snapshot value of songs:  Wagon Wheel|Her Diamonds|Waterfalls
flutter: String songList inside .then() after assignment:  Wagon Wheel|Her Diamonds|Waterfalls

**The function skips right past the .get() and immediate returns ... I know this probably has something to do with forcing the system to wait for that value to come back from FS...but I don't know how to handle it.

回答1:

That's the expected behavior with a then() block: the code inside that block is called asynchronously once the data has been loaded, so call code that requires the data has to be inside of the then() block.

Luckily Dart has an await keyword to make this easier. It essentially replaces the then() block:

Future<String> getSetList () async {
  String songList = 'Loading.....';
  DocumentReference set01DocRef = 
  Firestore.instance.collection('sets').document('SET01');

  snapshot = await set01DocRef.get();
  print('String songList inside .then() before assignment:  ' + songList);     
  //Wagon Wheel|Her Diamonds|Waterfalls
  print('Snapshot value of songs:  ' + snapshot['songs']);         //Wagon 
  Wheel|Her Diamonds|Waterfalls
  songList = snapshot['songs'];     
  print('String songList inside .then() after assignment:  ' + songList);     
  //Wagon Wheel|Her Diamonds|Waterfalls

  print('Bueller? Bueller??');
  print('String songList outside of .then():  ' + songList);  
  return songList;
}

Note that any calls to getSetList() must now also use await:

var setlist = await getSetList();