I want to check if a Future<dynamic> is not yet completed after 500 millis.

RaisedButton(
  onPressed: () async {

    setState(() {
      isLoading = true;
    });

    dynamic responseBody;

    Future.delayed(Duration(milliseconds: 500), () {
      print(responseBody == null); // always false, so it never null, even uncompleted
      // if (responseBody != null) {
      //   isLoading = false;
      // }
    });

    NetworkHelper n = NetworkHelper(queryFinalUrl);
    responseBody = await n.getData();
  },
)
import 'package:http/http.dart' as http;
import 'dart:convert';

class NetworkHelper {
  NetworkHelper(this.url);

  final String url;
  Future getData() async {
    http.Response response = await http.get(this.url);

    String responseBody = response.body;
    return jsonDecode(responseBody);
  }
}

I tried to check my dynamic is null and responseBody == null , but it seems never null.

Update for details:

OK, I have a loading indicator / loading spinner which will cover fullscreen using Visibility() which I need to display once I pressed the button. So you might noticed the code isLoading is the visibility bool. So my idea is , I want to add on another timer counter Future.delayed immediately once button is pressed, so that is counts for 500 millis, and if:

  1. 500ms has finished, and responseBody is not received yet , continue display the loading indicator

  2. 500ms has finished and responseBody is completed, dismiss the loading indicator

Let's say responseBody completed in 400ms, Loading indicator must persist for another 100ms before it can be dismissed

I hope this details is clear for you. :) Sorry for inconvenience.

Yes, I'm aware I need to put an await while waiting for fetching web data

I show the loading indicator by setState()

So to conclude, this is why I wanna check if a Future<dynamic> is completed or uncompleted


Solution 1: jamesdlin

Your responseBody == null check never succeeds because you do:

responseBody = n.getData();

which unconditionally assigns responseBody a Future. responseBody therefore will always be assigned a Future, regardless of whether it's complete or not. You instead could do:

responseBody = await n.getData();

which will assign responseBody the value of the Future only after the Future completes.

Alternatively, you could use Future.timeout:

NetworkHelper n = NetworkHelper(queryFinalUrl);
try {
  dynamic responseBody = await n.getData().timeout(Duration(milliseconds: 100));
  ...
} on TimeoutException {
  isLoading = false;
}