Open purplenoodlesoop opened 2 years ago
Hi @purplenoodlesoop 👋 Thanks for opening an issue!
When using bloc you can make use of emit.forEach
and emit.onEach
to handle reacting to an incoming stream. The subscription is automatically managed for you and you don't have to worry about cancelations. I'll think about this proposal a bit more but I'm not convinced that this would add a lot of value because while there will be fewer lines of code written, the code will be less explicit/clear.
@felangel thanks for the response!
When using bloc you can make use of emit.forEach and emit.onEach to handle reacting to an incoming stream.
This is certainly very true, but that capability is limited to Bloc
s only – mixins would allow adding that automatic subscription management to any Closable
– a Cubit
or even a custom implementation of the interface.
...this would add a lot of value because while there will be fewer lines of code written, the code will be less explicit/clear.
I also agree with the fact that it will make code a bit more "magical", but besides cutting the amount of code significantly, removing 2 out of 3 steps from the whole pipeline, mixins will make code less error-prone and further help with reducing the learning curve – it is possible to forget to cancel a StreamSubscription
or a CancelableOperation
.
This is certainly very true, but that capability is limited to Blocs only – mixins would allow adding that automatic subscription management to any Closable – a Cubit or even a custom implementation of the interface.
Yup definitely agree it would be especially useful for Cubits.
I also agree with the fact that it will make code a bit more "magical", but besides cutting the amount of code significantly, removing 2 out of 3 steps from the whole pipeline, mixins will make code less error-prone and further help with reducing the learning curve – it is possible to forget to cancel a StreamSubscription or a CancelableOperation.
Yeah definitely agree. I'll leave this open for a bit and try to get more feedback from the community to inform the decision.
Thanks again! 💙
They are related, but are not limited to: Bloc-to-Bloc/Cubit-to-Cubit/any other combination communications,
Hi there ! This is really something that is highly discouraged due to the declarative nature of the api
Hi @Gene-Dana!
Hi there ! This is really something that is highly discouraged due to the declarative nature of the API
Sorry, but I think we are talking about different things. Bloc-to-Bloc communication is not discouraged, does not breaks declarativity and there is a whole section in documentation dedicated to it.
Hi @purplenoodlesoop ! Thanks for this issue.
A major disadvantage is that including mixins might increase the complexity of the library significantly for newcomers. I believe it is easier to conceptualise a method such as emit.OnEach
and emit.ForEach
than a mixin for new developers. I do agree with @felangel , making use of mixins can make the code "less explicit/clear".
However, having said this, I think the methods that the Emitter
exposes can be useful for Cubit
. Although, in practice, I always tend to rely on Bloc
rather than Cubit
unless there is very low complexity, and I consider listening to a stream complex enough to use a Bloc
.
Hence, I think we can ask ourselves if we want Cubit
to have access to methods similar to emit.OnEach
and emit.ForEach
? If so, perhaps a mixin might be a possible solution. Although it comes with some caveats.
Regarding the BlocAsyncMixin
I think this is very interesting. Since discussing the similarities of Bloc to Automata theory in #3162 , I've been thinking that it might be a good idea to have a concept of a FinalState
. In other words, a state that when reached terminates the bloc (can not emit new states). One could handle when a FinalState
is reached and close the resources that are no longer required. I wonder if this might be applicable or of any help to the idea of the cancellable
method.
I hope this feedback helps.
Hi @felangel!
Description
There are a few common patterns that are used across
Bloc
s andCubit
s that require quite a few lines of boilerplate code and are error-prone.They are related, but are not limited to: Bloc-to-Bloc/Cubit-to-Cubit/any other combination communications, Repository consumption (sending an event when a new entity is emitted by Repository), logging, and more.
Those patterns follow the same sequence of actions:
Bloc
orCubit
close
methodThere are three main cases with that behavior:
1) Listening to a stream to perform any side effects 2) Reacting to stream with events (a subset of the first case) 3) Performing cancelable async operations (#3069)
Desired Solution
An elegant solution to that problem can be implemented through the help of mixins. For each case, the own mixin can be created.
1)
BlocListeningMixin
onClosable
minimally containinglistenToStream
andlistenToStreamable
methods. 2)BlocReactingMixin
onBlocListeningMixin
andBlocEventSink
minimally containingreactToStream
andreactToStreamable
methods. 3)BlocAsyncMixin
onClosable
minimally containingcancelable
method.Of course, those methods are only minimal content.
Alternatives Considered
An alternative will be to not change anything and keep track of cancelable objects by hand. That approach certainly works, but requires more code, is more error-prone, and requires more mental load on the developer.
Additional Context
A sample and rough implementation of
BlocListeningMixin
would look something like that. Note, that methods return an instance ofStreamSubscription
for cases when it should be canceled manually before the closing of theClosable
.