Flutter/Dart - calling a function that is a Future<String> ... but needs to return only a String
Solution 1
When do you need to call the future?
You can always create a tmp variable and try to load it. You cannot randomly put futures into the build process. You need to grab the data then call setState to notify the widget if the view has changed.
String _setList = null;
//initState called when the widget is mounted.
void initState() {
super.initState();
if(_setList == null){
getSetList().then(
(String s) => setState(() {_setList = s;})
);
}
}
@override
Widget build(BuildContext context) {
String setList = _setList;
print('In widget: ' + setList.toString()); //shows as instance of Future<String>
if(setList != null){
//List<String> items = setList.split('|');
List<String> items = ['Red','White','Blue'];
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
} else { return const CircularProgressIndicator(); }
//Create a progress circle.
I hope my set state does not have any sytax errors.
https://docs.flutter.io/flutter/widgets/State/setState.html
https://docs.flutter.io/flutter/widgets/State/initState.html
Solution 2
you can't use await in a function that is not async, which means the use
var setList = await getSetList();
in your build function is wrong.
Related videos on Youtube
robertsirwin
Updated on June 04, 2022Comments
-
robertsirwin almost 2 years
I have an async function that is calling out to Firestore to pull in a data value. I got a lot of help in a previous post...learned a lot...and wanted to start over with hopefully a cleaner question. So I have the following function
Future<String> getSetList () async { DocumentReference set01DocRef = Firestore.instance.collection('sets').document('SET01'); var snapshot = await set01DocRef.get(); songList = snapshot['songs']; //works, get expected text value from FS return songList; }
This function logic works...I can print() out the songList var (string var) to the console and I see the value from Firestore. When I try to call the function:
@override Widget build(BuildContext context) { var setList = getSetList(); print('In widget: ' + setList.toString()); //shows as instance of Future<String> //List<String> items = setList.split('|'); List<String> items = ['Red','White','Blue']; return new Scaffold( appBar: new AppBar( title: new Text(widget.title), ),
That setList variable is not a String. When I print it [print(setList.toString()] it shows as an instance of Future String.
I tried using:
var setList = await getSetList();
but that shows an error on the await.Any ideas appreciated.
-
Frank van Puffelen over 5 yearsAs stated in the comments in my answer to your previous question, when you call an
async
method you need to useawait
to get the value (instead of theFuture
value). And any method that usesawait
will itself have to be marked asasync
. -
robertsirwin over 5 yearsThank you for your continued help...I apologize that I still don't 'get it'. I will continue to read and try.
-
-
user1462442 over 5 yearsI cannot believe I got the syntax right. I never ran it. I wrote it has a simple example
-
robertsirwin over 5 yearsThe only thing I had to tweak was 'const setList...' needed to be 'String setList ...' Thank you very much.
-
PravyNandas about 3 yearsA great example @user1462442. Thanks. Minor tweaks needed in Flutter 2.0.5 (Nullability issues primarily). String _setList = ""; (null cannot be assigned to type String).