user13456401
user13456401

Reputation: 479

How to implement async/await in Flutter

I have this function that performs some firestore operations and retrieve the data.

But the problem is this returns an empty value. The reason I found was, it returns the value before fetching the data, it doesn't wait until it retrieves the data.

Here is my code. I have print some print statements to check the order of the execution.


getNewsOnSearchBar() {
  final String _collection = 'news';
  final Firestore _fireStore = Firestore.instance;
  var newsList = [];

  print("1");
  getData() async {
    print("2");
    return await _fireStore.collection(_collection).getDocuments();
  }

  getData().then((val) async{
    if (val.documents.length > 0) {
      print("3");
      for (int i = 0; i < val.documents.length; i++) {        
        newsList.add(await val.documents[i].data["headline"]);
      }
    } else {
      print("Not Found");
    }
  });

  print("4");

  return ok;
}

And the output is:

I/flutter (17145): 1
I/flutter (17145): 2
I/flutter (17145): 4 // 4 prints before 3
I/flutter (17145): 3

Output I need is:

I/flutter (17145): 1
I/flutter (17145): 2
I/flutter (17145): 3
I/flutter (17145): 4

Can someone help me?

Upvotes: 0

Views: 49

Answers (2)

HII
HII

Reputation: 4109

When you want to wait for a value from a Future as in your case, don't use then, use await:

Future<int> myFunc() {
  return Future.delayed(Duration(seconds: 1), () => 0);
}

void main() async {
  final int result = await myFunc();
  print(result);//0
}

In your case, you would like to do something similar (you may change it according to your needs):

getNewsOnSearchBar() async {
  final String _collection = 'news';
  final Firestore _fireStore = Firestore.instance;
  var newsList = [];

  print("1");
  getData() async {
    print("2");
    return await _fireStore.collection(_collection).getDocuments();
  }

  final ref = await getData();
  if (ref.documents.length > 0) {
    print("3");
    for (int i = 0; i < ref.documents.length; i++) {
      newsList.add(await ref.documents[i].data["headline"]);
    }
  } else {
    print("Not Found");
  }

  print("4");

  return ok;
}

Upvotes: 1

Shubham Gupta
Shubham Gupta

Reputation: 1997

Instead of using then you can use await and that should solve your issue. Here is how your code will look with changes and I strongly recommend to specify the type of data that your function will return.

getNewsOnSearchBar() async {
    final String _collection = 'news';
    final Firestore _fireStore = Firestore.instance;
    var newsList = [];

    print("1");

    Future<QuerySnapshot> getData() async {
        print("2");
        return await _fireStore.collection(_collection).getDocuments();
    }

    QuerySnapshot val = await getData();
    if (val.documents.length > 0) {
        print("3");
        for (int i = 0; i < val.documents.length; i++) {        
           newsList.add(val.documents[i].data["headline"]);
        }
    } else {
       print("Not Found");
    }
    print("4");
    return ok;
}

Upvotes: 1

Related Questions