Reputation: 63
I want to listen to a stream but I don't want to listen to the previous events only the upcoming ones
I tried using skip after I checked the stream length but somehow it doesn't work
final skipCount =await CartBloc().state.length;
listenForSuccess = CartBloc().state.skip(skipCount).listen((var state) {
//Do Something
listenForSuccess.cancel();
}
//CartBloc is a singleton so am not creating a new instance by calling //CartBloc()
Upvotes: 0
Views: 1077
Reputation: 71623
If it makes sense to only listen for some of the events of a stream, then that stream should be a broadcast stream.
Listening to a broadcast stream will only provide the new events that are sent after you listen. It should work like what you want.
That is: Just listen, you don't need to do anything extra to skip previous events, they have already been sent out, and they are not waiting for you.
Listening to a single-subscription stream will give you all the events, which is usually necessary because:
You are the only one listening to that stream, and
The events usually represent one data entity which has just been chunked while reading it asynchronously.
If your stream does not act as either of those, then it's a curious stream (not impossible, but not something you can create using just the dart:async
library).
A single-subscription stream's asBroadcast
stream will likely buffer events until the first listen, then start acting like a broadcast stream. That may be what you are dealing with here. In that case, try to change the code to be a proper broadcast stream.
In any case, what you are trying here will not work for any traditional stream.
Doing .length
on any stream will wait for the entire stream to complete. There won't be any further events after that, and if it's not a stream that ever gets closed, you will wait forever.
On a broadcast stream, that won't block any other code from listening on the same stream, but the await
will make sure that the following code won't happen before the stream is done.
On a single-subscription stream, no other code can listen to the same stream after you have called .length
, so the following code will throw if it's ever reached.
So, If the stream is a broadcast stream, then you don't need to do anything. Since I can't see the code for CardBloc
, I can't say what it really is. Let's assume it's a single-subscription stream. Then the code in CardBloc
should be changed to create the stream using a StreamController.broadcast()
controller. You can't create a broadcasts stream using an async*
method. Alternatively, you can convert a create a broadcast stream from any stream by doing:
var broadcastStream = stream.asBroadcastStream()..listen(null).cancel();
Listening once to the returned stream ensures that it starts producing events immediately, instead of waiting until you listen to it the first time - if that is what you want.
Upvotes: 1