From 561709d223495e86cef2f8fc2697b751ddf55141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Dziwota?= Date: Sat, 23 Apr 2022 19:41:24 +0200 Subject: [PATCH] add TypedMiddlewareBase abstraction --- CHANGELOG.md | 8 +++++-- README.md | 12 +++++++++- lib/src/utils.dart | 56 +++++++++++++++++++++++++++++++++++++------- test/test_data.dart | 10 ++++++++ test/utils_test.dart | 5 ++++ 5 files changed, 80 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ec2cc7..dfde093 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ -5.0.0 +# 5.1.0 + + * Added option to create typed middelware class by extending `TypedMiddlewareBase` + +# 5.0.0 * Preview version, same as 5.0.0-nullsafety -5.0.0-nullsafety +# 5.0.0-nullsafety * Update to null safety * Drop package:coverage diff --git a/README.md b/README.md index 86f6c8f..626de92 100644 --- a/README.md +++ b/README.md @@ -100,12 +100,22 @@ loggingMiddleware(Store store, action, NextDispatcher next) { next(action); } +// You can also create a middleware class bound to exact action type. +class CallMiddleware extends TypedMiddlewareBase { + @override + dynamic dispatch( + Store store, CallAction action, NextDispatcher next) { + service.call(action.phone); + next(action); + } +} + main() { // Create the store with our Reducer and Middleware final store = new Store( counterReducer, initialState: 0, - middleware: [loggingMiddleware], + middleware: [loggingMiddleware, CallMiddleware()], ); // Render our State right away diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 79df9bc..a6d2dba 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -115,6 +115,50 @@ class TypedReducer implements ReducerClass { } } +/// A convenience type to build a Middleware to an Action +/// of a specific type. Allows for Type Safe Middleware. +/// +/// ### Example +/// ``` +/// class CustomMiddleware extends TypedMiddlewareBase { +/// @override +/// dynamic dispatch( +/// Store store, +/// CustomAction action, +/// NextDispatcher next, +/// ) { +/// next(action); +/// } +/// } +/// ``` +/// We will then wire up specific types of actions to a List of Middleware +/// that handle those actions. +/// ``` +/// final List> middleware = [ +/// CallMiddleware(), +/// LoginMiddleware(), +/// LogoutMiddleware(), +/// ]; +/// ``` +abstract class TypedMiddlewareBase + implements MiddlewareClass { + /// A [Middleware] function that only works on actions of a specific type. + dynamic dispatch( + Store store, + Action action, + NextDispatcher next, + ); + + @override + dynamic call(Store store, dynamic action, NextDispatcher next) { + if (action is Action) { + return dispatch(store, action, next); + } else { + return next(action); + } + } +} + /// A convenience type for binding a piece of Middleware to an Action /// of a specific type. Allows for Type Safe Middleware and reduces boilerplate. /// @@ -211,7 +255,8 @@ class TypedReducer implements ReducerClass { /// new TypedMiddleware(saveItemsMiddleware), /// ]; /// ``` -class TypedMiddleware implements MiddlewareClass { +class TypedMiddleware + extends TypedMiddlewareBase { /// A [Middleware] function that only works on actions of a specific type. final dynamic Function( Store store, @@ -224,13 +269,8 @@ class TypedMiddleware implements MiddlewareClass { TypedMiddleware(this.middleware); @override - dynamic call(Store store, dynamic action, NextDispatcher next) { - if (action is Action) { - return middleware(store, action, next); - } else { - return next(action); - } - } + dynamic dispatch(Store store, Action action, NextDispatcher next) => + middleware(store, action, next); } /// Defines a utility function that combines several reducers. diff --git a/test/test_data.dart b/test/test_data.dart index fc1acc8..43e2c29 100644 --- a/test/test_data.dart +++ b/test/test_data.dart @@ -89,8 +89,18 @@ class ThunkMiddleware implements MiddlewareClass { } } +class TypedTestMiddleware extends TypedMiddlewareBase { + @override + dynamic dispatch( + Store store, TypedTestAction action, NextDispatcher next) { + next('TypedTestMiddleware called'); + } +} + class TestAction1 {} class TestAction2 {} class TestAction3 {} + +class TypedTestAction {} diff --git a/test/utils_test.dart b/test/utils_test.dart index 53b0719..94eadcf 100644 --- a/test/utils_test.dart +++ b/test/utils_test.dart @@ -108,6 +108,7 @@ void main() { middleware: [ TypedMiddleware(testAction1Middleware), TypedMiddleware(testAction2Middleware), + TypedTestMiddleware(), ], ); @@ -116,6 +117,9 @@ void main() { store.dispatch(TestAction2()); expect(store.state, 'testAction2Middleware called'); + + store.dispatch(TypedTestAction()); + expect(store.state, 'TypedTestMiddleware called'); }); test( @@ -127,6 +131,7 @@ void main() { initialState: initialState, middleware: [ TypedMiddleware(testAction1Middleware), + TypedTestMiddleware(), ], );