Hussein Al-Mosawi
Hussein Al-Mosawi

Reputation: 1694

Convert a Stream to a Future in Flutter

a Flutter beginner here so if my question is stupid don't mind it...

How can I convert a Stream to a Future?

I have a Stream that just calls the requested URL multiple times because it's a Stream. I want to be able to get the data and not the loading state... Because I always just get loading forever

Is there something like Future.fromStream() function somewhere and I'm missing it?

Can I achieve this?

I didn't provide any code because I think it's not needed if you need the code, I can edit the question

Upvotes: 6

Views: 6390

Answers (4)

tronic
tronic

Reputation: 516

extension StreamUtils<T> on Stream<T> {
  Future<T> toFuture() {
    Completer<T> completer = Completer();
    T? value;
    listen(
      (event) => value = event,
      onDone: () {
        if (value != null) {
          completer.complete(value);
        } else {
          completer.completeError("noData");
        }
      },
    );
    return completer.future;
  }
}

Upvotes: 0

Michael Tamm
Michael Tamm

Reputation: 943

There are several ways to convert a Stream<T> into a Future<T> provided by the Stream class:

Suppose you have a Variable stream of type Stream<T>, than

  • stream.first converts the stream into a future, which comletes with the first element of the stream.
  • stream.single converts the stream into a future, which comletes with the single element of the stream. (The future will complete with an error, if the stream is empty or has more than one element.)
  • stream.last converts the stream into a future, which comletes with the last element of the stream.
  • stream.elementAt(n) converts the stream into a future, which comletes with the nth element of the stream.
  • stream.firstWhere(test) converts the stream into a future, which completes with the first element of the stream, which satisfies the given test function.
  • stream.lastWhere(test) converts the stream into a future, which completes with the last element of the stream, which satisfies the given test function.
  • stream.singleWhere(test) converts the stream into a future, which completes with the single element of the stream, which satisfies the given test function. (The future will complete with an error if there is no such element or if there are multiple elements, for which the given test function returns true.)
  • stream.reduce(combine) will combine all elements in the stream into a single element by repeatedly applying the given combine function.

Upvotes: 0

xion
xion

Reputation: 1369

Stream and Future are two different concepts.

As you are using, stream is keeping the data updated, and Future is just one time. Example of using stream: Shopping Cart, listing of items Example of using future: getUserDetails after login.

If you're using stream, then you can use streambuilder to build your UI

StreamBuilder<User>(
  stream: userBloc.author, // your stream here
  builder:
      (BuildContext context, AsyncSnapshot<User> snapshot) {
    if (snapshot.connectionState == ConnectionState.active && snapshot.hasData) {
      // do your work here
    } else {
      return CircularprogressIndicator();
    }
  },
)

Upvotes: 0

ikerfah
ikerfah

Reputation: 2862

Stream has firstWhere method, this will return Future

_profileService.profileStream.firstWhere((element) => false);

Upvotes: 7

Related Questions