Flutter/Dart - calling a function that is a Future<String> ... but needs to return only a String

18,633

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.

Share:
18,633

Related videos on Youtube

robertsirwin
Author by

robertsirwin

Updated on June 04, 2022

Comments

  • robertsirwin
    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
      Frank van Puffelen over 5 years
      As stated in the comments in my answer to your previous question, when you call an async method you need to use await to get the value (instead of the Future value). And any method that uses await will itself have to be marked as async.
    • robertsirwin
      robertsirwin over 5 years
      Thank you for your continued help...I apologize that I still don't 'get it'. I will continue to read and try.
  • user1462442
    user1462442 over 5 years
    I cannot believe I got the syntax right. I never ran it. I wrote it has a simple example
  • robertsirwin
    robertsirwin over 5 years
    The only thing I had to tweak was 'const setList...' needed to be 'String setList ...' Thank you very much.
  • PravyNandas
    PravyNandas about 3 years
    A great example @user1462442. Thanks. Minor tweaks needed in Flutter 2.0.5 (Nullability issues primarily). String _setList = ""; (null cannot be assigned to type String).