Skip to content

Instantly share code, notes, and snippets.

@II11II
Created March 26, 2024 11:41
Show Gist options
  • Save II11II/9389ac6ad673e9d54e86957388a0d58c to your computer and use it in GitHub Desktop.
Save II11II/9389ac6ad673e9d54e86957388a0d58c to your computer and use it in GitHub Desktop.
Various types of event registrations in bloc
import 'dart:async';
import 'package:bloc/bloc.dart';
void main() async{
final pushNotification = PushNotification();
final v1 = V1PushNotificationBloc(pushNotification: pushNotification);
v1.add(PushNotificationEvent.started());
v1.add(PushNotificationEvent.subscribe("V1PushNotificationBlocTopic"));
await Future.delayed(Duration(seconds: 1), (){
print("\n\n\n");
});
final v2 = V2PushNotificationBloc(pushNotification: pushNotification);
v2.add(PushNotificationEvent.started());
v2.add(PushNotificationEvent.subscribe("V2PushNotificationBlocTopic"));
}
class PushNotification {
Future<String> initNotification() async {
await Future.delayed(Duration(milliseconds: 200));
return "token";
}
Future<void> subscribeToTopic(String topic) async {
await Future.delayed(Duration(milliseconds: 200));
print("PushNotification.subscribeToTopic($topic) is called");
}
Future<void> unsubscribeFromTopic(String topic) async {
await Future.delayed(Duration(milliseconds: 200));
print("PushNotification.unsubscribeFromTopic($topic) is called");
}
}
EventTransformer<Event> sequential<Event>() {
return (events, mapper) => events.asyncExpand(mapper);
}
sealed class PushNotificationEvent {
const factory PushNotificationEvent.started() = _Started;
const factory PushNotificationEvent.subscribe(String topicType) = _Subscribe;
const factory PushNotificationEvent.unsubscribe(String topicType) =
_Unsubscribe;
}
class _Started implements PushNotificationEvent {
const _Started();
}
class _Subscribe implements PushNotificationEvent {
final String topicType;
const _Subscribe(this.topicType);
}
class _Unsubscribe implements PushNotificationEvent {
final String topicType;
const _Unsubscribe(this.topicType);
}
sealed class PushNotificationState {
const factory PushNotificationState.initial() = _Initial;
const factory PushNotificationState.granted({required String token}) =
_Granted;
const factory PushNotificationState.denied() = _Denied;
}
class _Initial implements PushNotificationState {
const _Initial();
}
class _Granted implements PushNotificationState {
final String token;
const _Granted({required this.token});
}
class _Denied implements PushNotificationState {
const _Denied();
}
class V1PushNotificationBloc
extends Bloc<PushNotificationEvent, PushNotificationState> {
V1PushNotificationBloc({required PushNotification pushNotification})
: _pushNotification = pushNotification,
super(const PushNotificationState.initial()) {
on<_Started>(_onStarted, transformer: sequential());
on<_Subscribe>(_onSubscribe, transformer: sequential());
on<_Unsubscribe>(_onUnsubscribe, transformer: sequential());
}
final PushNotification _pushNotification;
FutureOr<void> _onStarted(
_Started event, Emitter<PushNotificationState> emit) async {
print(
"V1PushNotificationBloc._onStarted is called-The current state is PushNotificationState.initial");
String token = await _pushNotification.initNotification();
emit(PushNotificationState.granted(token: token));
print(
"V1PushNotificationBloc._onStarted is called-The current state is PushNotificationState.granted");
}
FutureOr<void> _onSubscribe(
_Subscribe event, Emitter<PushNotificationState> emit) =>
switch (state) {
final _Granted grantedState => (_Granted grantedState) async {
await _pushNotification.subscribeToTopic(event.topicType);
print(
"V1PushNotificationBloc._onSubscribe is called-Topic type: ${event.topicType}-The current state is granted");
}(grantedState),
_ => () {
print(
"V1PushNotificationBloc._onSubscribe is called-Topic type: ${event.topicType}-The current state is initial");
}()
};
FutureOr<void> _onUnsubscribe(
_Unsubscribe event, Emitter<PushNotificationState> emit) =>
switch (state) {
final _Granted grantedState => (_Granted grantedState) async {
await _pushNotification.unsubscribeFromTopic(event.topicType);
print(
"V1PushNotificationBloc._onUnsubscribe is called-Topic type: ${event.topicType}-The current state is granted");
}(grantedState),
_ => () {
print(
"V1PushNotificationBloc._onUnsubscribe is called-Topic type: ${event.topicType}-The current state is initial");
}()
};
}
class V2PushNotificationBloc
extends Bloc<PushNotificationEvent, PushNotificationState> {
V2PushNotificationBloc({required PushNotification pushNotification})
: _pushNotification = pushNotification,
super(const PushNotificationState.initial()) {
on<PushNotificationEvent>(
(event, emit) => switch (event) {
_Started() => _onStarted(event, emit),
_Subscribe() => _onSubscribe(event, emit),
_Unsubscribe() => _onUnsubscribe(event, emit),
},
transformer: sequential());
}
final PushNotification _pushNotification;
FutureOr<void> _onStarted(
_Started event, Emitter<PushNotificationState> emit) async {
print(
"V2PushNotificationBloc._onStarted is called-The current state is PushNotificationState.initial");
String token = await _pushNotification.initNotification();
emit(PushNotificationState.granted(token: token));
print(
"V2PushNotificationBloc._onStarted is called-The current state is PushNotificationState.granted");
}
FutureOr<void> _onSubscribe(
_Subscribe event, Emitter<PushNotificationState> emit) =>
switch (state) {
final _Granted grantedState => (_Granted grantedState) async {
await _pushNotification.subscribeToTopic(event.topicType);
print(
"V2PushNotificationBloc._onSubscribe is called-Topic type: ${event.topicType}-The current state is granted");
}(grantedState),
_ => () {
print(
"V2PushNotificationBloc._onSubscribe is called-Topic type: ${event.topicType}-The current state is initial");
}()
};
FutureOr<void> _onUnsubscribe(
_Unsubscribe event, Emitter<PushNotificationState> emit) =>
switch (state) {
final _Granted grantedState => (_Granted grantedState) async {
await _pushNotification.unsubscribeFromTopic(event.topicType);
print(
"V2PushNotificationBloc._onUnsubscribe is called-Topic type: ${event.topicType}-The current state is granted");
}(grantedState),
_ => () {
print(
"V2PushNotificationBloc._onUnsubscribe is called-Topic type: ${event.topicType}-The current state is initial");
}()
};
}
/// Output:
// V1PushNotificationBloc._onStarted is called-The current state is PushNotificationState.initial
// V1PushNotificationBloc._onSubscribe is called-Topic type: V1PushNotificationBlocTopic-The current state is initial
// V1PushNotificationBloc._onStarted is called-The current state is PushNotificationState.granted
//
//
//
//
// V2PushNotificationBloc._onStarted is called-The current state is PushNotificationState.initial
// V2PushNotificationBloc._onStarted is called-The current state is PushNotificationState.granted
// PushNotification.subscribeToTopic(V2PushNotificationBlocTopic) is called
// V2PushNotificationBloc._onSubscribe is called-Topic type: V2PushNotificationBlocTopic-The current state is granted
@II11II
Copy link
Author

II11II commented Mar 26, 2024

sequential() works incorrectly in V1PushNotificationBloc, however it works correctly in V2PushNotificationBloc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment