skip to Main Content

I have to query different firestore collections from a single flutter screen. A sample looks like

final membersRef = db.collection("members").doc(memberId);
final noOfEventsRef = db.collection('events').where('year', isEqualTo: thisYear).count();
final myAttendance = db.collection('events').where('year', isEqualTo: thisYear).where('attendees', arrayContains: widget.memberId).count();
final dailyQuoteRef = db.collection('daily-quote').doc('JVX9rjht1P6SK5rtg8');

So first query returns a single document from members collection, the second query returns the # of events of a particular year and so on.

As of now I use a big nested then() call to get the data and convert into a model before display.

membersRef.get().then((doc) {
        final data = doc.data() as Map<String, dynamic>;
        member = Member.fromJson(data);

        noOfEventsRef.get().then((event) {
          eventCount = event.count;

          myAttendance.get().then((attendance) {
            attendanceCount = attendance.count;

            dailyQuoteRef.get().then((DocumentSnapshot doc) {
              final finalQuote = doc.data() as Map<String, dynamic>;
              quote = Quote.fromJson(finalQuote);
            }).whenComplete(() {
              setState(() {
                loading = false;
              });
            });
          });
        });
      },
      onError: (e) => print("Error getting document: $e"),
    );

This feels like callback hell. How to properly code this!? Help much appreciated. Thanks

2

Answers


  1. Try using await that will make code more readable and easy to understand

    getData() async{
     try {
      final doc = await membersRef.get();
      final data = doc.data() as Map<String, dynamic>;
      member = Member.fromJson(data);
    
      final event = await noOfEventsRef.get();
      eventCount = event.count;
    
      final attendance = await myAttendance.get();
      attendanceCount = attendance.count;
    
      final quoteDoc = await dailyQuoteRef.get();
      final finalQuote = quoteDoc.data() as Map<String, dynamic>;
      quote = Quote.fromJson(finalQuote);
    
      setState(() {
        loading = false;
      });
    } catch (e) {
      print("Error getting document: $e");
     }
    }
    

    call getdata() from initstate.

    Login or Signup to reply.
  2. An alternative solution is to use async/await with Future.wait()

    Future<void> loadData() async {
    try {
      final memberDoc = await membersRef.get();
      final data = memberDoc.data() as Map<String, dynamic>;
      member = Member.fromJson(data);
    
      final eventCountQuery = await noOfEventsRef.get();
      eventCount = eventCountQuery.count;
    
      final attendanceQuery = await myAttendance.get();
      attendanceCount = attendanceQuery.count;
    
      final dailyQuoteDoc = await dailyQuoteRef.get();
      final finalQuote = dailyQuoteDoc.data() as Map<String, dynamic>;
      quote = Quote.fromJson(finalQuote);
    
      setState(() {
        loading = false;
      });
    } catch (e) {
      print('Error getting data: $e');
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search