Why is print(snapshot.hasData) returning true?

Viewed 4556

I must be misunderstanding the hasData method for a QuerySnaphot. In my StreamBuilder I want to return a widget informing the user there are no items in the collection queried. I've deleted the collection in Firestore so there's definitely no data there. But when I run the following code:

StreamBuilder<QuerySnapshot>(
  stream: Firestore.instance
    .collection('Events')
    .where("bandId", isEqualTo: identifier)
    .snapshots(),
    builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
      if (!snapshot.hasData) {
        print('code here is being executed 1');// This gets executed
        return Text('helllllp');
      } else {
        print('Code here is being executed2'); //And this gets executed 
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return new Text('Loading...');
          default:
            return new ListView(
              children:
                snapshot.data.documents.map((DocumentSnapshot document) {
                  return CustomCard(
                    event: document['event'],
                    location: document['location'],
                    service: document['service'],
                    date: document['date'].toDate(),
                  );
                }).toList(),
              );
            }
          }
        },
      ),

All I want to do is return a widget informing user if the snapshot is empty. For example Text('You have no messages')

1 Answers

The problem here is that snapshots() will also return a QuerySnapshot when the query returns no documents. Thus, you could expand your condition like this:

if (!snapshot.hasData || snapshot.data.documents.isEmpty) {
  return Text('You have no messages.');
} else {
  ...
}

Although, realistically you should not return You have no messages when snapshot.data is null because it is null before the query is completed. Hence, I would go for something like this:

if (!snapshot.hasData) {
  return Text('Loading...');
} 
if (snapshot.data.documents.isEmpty) {
  return Text('You have no messages.');  
}
return ListView(..);

This ignores error handling, however, that can also be added.
Notice that snapshot.hasData is an alternative to determining connection state using snapshot.connectionState.

Related