This guide helps you migrate to the new functional API in v2.0.
The v2.0 release completely redesigns the API to use a functional approach without requiring class extension.
Old Pattern (v1.x):
// Had to extend a class
class MyEvents extends MayrEventSetup {
@override
void registerListeners() {
MayrEvents.on<UserEvent>(UserListener());
}
}
// Had to call init
void main() async {
await MyEvents().init();
runApp(MyApp());
}
// Fire events
await MayrEvents.instance.fire(UserEvent());New Pattern (v2.0):
// Just a function - no class extension needed!
void setupEvents() {
MayrEvents.on<UserEvent>(UserListener());
// Can add keyed handlers
MayrEvents.beforeHandle('logger', (event, listener) async {
print('Handling ${event.runtimeType}');
});
}
// Call setup function
void main() {
setupEvents();
runApp(MyApp());
}
// Fire events - simpler!
await MayrEvents.fire(UserEvent());Before:
class AppEvents extends MayrEventSetup {
@override
void registerListeners() {
MayrEvents.on<UserRegisteredEvent>(SendWelcomeEmailListener());
}
@override
Future<void> beforeHandle(event, listener) async {
print('Handling event');
}
}After:
void setupEvents() {
MayrEvents.on<UserRegisteredEvent>(SendWelcomeEmailListener());
// Convert hooks to keyed handlers
MayrEvents.beforeHandle('app_logger', (event, listener) async {
print('Handling event');
});
}Before:
void main() async {
await AppEvents().init();
runApp(MyApp());
}After:
void main() {
setupEvents();
runApp(MyApp());
}Before:
await MayrEvents.instance.fire(UserRegisteredEvent(userId, email));After:
await MayrEvents.fire(UserRegisteredEvent(userId, email));Before (class-level hooks):
class AppEvents extends MayrEventSetup {
@override
Future<void> beforeHandle(event, listener) async {
// Hook logic
}
@override
Future<void> onError(event, error, stack) async {
// Error handling
}
}After (keyed handlers):
void setupEvents() {
MayrEvents.beforeHandle('logger', (event, listener) async {
// Hook logic
});
MayrEvents.onError('error_handler', (event, error, stack) async {
// Error handling
});
// NEW: shouldHandle validator
MayrEvents.shouldHandle('validator', (event) {
// Return false to prevent execution
return true;
});
}Events can now have their own hooks:
class UserRegisteredEvent extends MayrEvent {
final String userId;
final String email;
const UserRegisteredEvent(this.userId, this.email);
@override
Future<void> Function(MayrEvent, MayrListener)? get beforeHandle =>
(event, listener) async {
print('Event-specific hook');
};
@override
bool Function(MayrEvent)? get shouldHandle =>
(event) => (event as UserRegisteredEvent).userId.isNotEmpty;
@override
Future<void> Function(MayrEvent, Object, StackTrace)? get onError =>
(event, error, stack) async {
print('Event-specific error handler');
};
}Manage handlers with unique keys:
// Add handlers
MayrEvents.beforeHandle('logger', logCallback);
MayrEvents.beforeHandle('metrics', metricsCallback);
MayrEvents.onError('sentry', sentryCallback);
// Remove specific handlers
MayrEvents.removeBeforeHandler('logger');
MayrEvents.removeErrorHandler('sentry');New validation system:
MayrEvents.shouldHandle('rate_limiter', (event) {
// Return false to skip listener execution
return !isRateLimited();
});Clean up specific handlers:
MayrEvents.removeBeforeHandler('key');
MayrEvents.removeErrorHandler('key');
MayrEvents.removeShouldHandle('key');- MayrEventSetup removed - No longer exists
- No class extension - Use functional approach
- MayrEvents.instance removed - Use static methods directly
- Init method removed - Just call setup function
- Pure Dart - No Flutter dependency
- Simpler - No class boilerplate
- More flexible - Event-level hooks
- Better control - Keyed handler system
- Cleaner - Functional approach
- Universal - Pure Dart works everywhere
If you encounter issues during migration:
- Check the README for the latest examples
- Review the Quick Start Guide
- Look at the updated example app
- Open an issue on GitHub