flutterflutter-futurebuilder

How Do I Conditionally Display a Message When This Future Returns an Empty List?


I have a view whose body is a FutureBuilder that gets a list of items from a Supabase backend. I'd like to do some conditional logic after the database connection such that if there IS a connection but there are ZERO records to display, the view shows a bit of text indicating that.

I can't seem to get that to work. Here's the current code:

FutureBuilder(
  future: transactionRepo.getTxnsAndRelvars(),
  builder: (BuildContext context, AsyncSnapshot snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator.adaptive();
    } else if (snapshot.hasError) {
      return Center(child: Text('Error! ${snapshot.error}'));
    } else if (!snapshot.hasData) {
      return Text('No data present!'); // 1
    } else {
      return ListView.builder(
        itemCount: snapshot.data?.length,
        itemBuilder: (context, index) {
          if (snapshot.data.length > 0) {
            return GestureDetector(...); // the list of items
              } else {
                return Center(
                  child: Text('No Transactions Yet!'),
                );
              }
            },
          );
        }
      },
    );

Couple of things. The code at #1 above doesn't ever fire. The ConnectionState.waiting and ConnectionState.hasError bits both work, because I get a circular progress indicator while loading and I get an error message when something goes wrong.

But neither the !snapshot.hasData bit nor the else { return Center... bit ever fire, despite the fact that there's no data, no items, and nothing to show on-screen.

What am I missing here?


Solution

  • You should check whether the connection state is done and the snapshot's data is actually empty:

    ConnectionState.done && snapshot.data != null && snapshod.data.isEmpty.

    Introduce them before the final else:

    ...
    else if (snapshot.connectionState == ConnectionState.done &&
          snapshot.data != null &&
          snapshot.data!.isEmpty) {
        return const Center(
          child: Text("No transactions"),
        );
      }
    ...