deekay42
deekay42

Reputation: 636

Create Future based on result of another Future

I have a remote async firebase function "checkSubscription" that returns either "true" if the user has a valid subscription or or "N", where N signifies the number of remaining credits before the user runs out.

To track completion I have these two futures in my class:

Future<bool> hasSubscription;
Future<int> remaining;

Assume that the datatypes on these cannot be changed. The remote function is called like this:

CloudFunctions.instance
        .call(functionName: 'checkSubscription');

This function returns a Future<dynamic> with the result.

I'm struggling with the Future logic required to assign my two fields with the required types. Here is what I came up with

Future<void> checkIfUserHasSubscription() async {
    await Future < dynamic > remainingS = CloudFunctions.instance
        .call(functionName: 'isValid');

    if (remaining == "true")
      hasSubscription = true;
    else {
      hasSubscription = false;
      remaining = int.parse(remaining);
    }
  }

Obviously this doesn't work because I'm assigning a bool instead of a Future

Any advice?

Upvotes: 2

Views: 931

Answers (2)

lrn
lrn

Reputation: 71653

As I understand it, you want to have two futures that are completed at a later time. Those futures should be available immediately when you call the check function, but only be completed when you have the result.

For that, you should use a Completer.

I'll assume that you only call the check function once. If not, then you should create a new completer on each call, inside the function, and store the futures in mutable fields instead.

Future<bool> _hasSubscription;
Future<int> _remaining;
Future<boo> get hasSubscription => 
  _hasSubscription ?? throw StateError("Call checkIfUserHasSubscription first");  
Future<int> get remaining => 
  _remaining ?? throw StateError("Call checkIfUserHasSubscription first");
Future<void> checkIfUserHasSubscription() async {
  // Maybe: if (hasSubscription != null) return;
  var hasSubscriptionCompleter = Completer<bool>();
  var remainingCompleter = Completer<int>();
  _hasSubscription = hasSubscriptionCompleter.future;
  _remaining = remainingCompleter.future;
  var remainings = await
      CloudFunctions.instance.call(functionName: 'isValid');
  if (remaining == "true") {
    hasSubscriptionCompleter.complete(true);
    remainingCompleter.complete(0); // or never complete it.
  } else {
    hasSubscriptionCompleter.complete(false);
    remainingCompleter.complete(int.parse(remaining));
  }
}

Upvotes: 2

Miguel Ruivo
Miguel Ruivo

Reputation: 17756

You can instead assign a Future with your result:

hasSubscription = Future<bool>.value(true);

Upvotes: 0

Related Questions