Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have dispatch return a value #52

Merged
merged 5 commits into from
Nov 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions lib/src/store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ abstract class ReducerClass<State> {
/// counterReducer,
/// middleware: [loggingMiddleware],
/// );
typedef void Middleware<State>(
typedef dynamic Middleware<State>(
Store<State> store,
dynamic action,
NextDispatcher next,
Expand Down Expand Up @@ -101,7 +101,7 @@ typedef void Middleware<State>(
/// );
abstract class MiddlewareClass<State> {
/// A [Middleware] function that intercepts a dispatched action
void call(Store<State> store, dynamic action, NextDispatcher next);
dynamic call(Store<State> store, dynamic action, NextDispatcher next);
}

/// The contract between one piece of middleware and the next in the chain. Use
Expand All @@ -111,7 +111,7 @@ abstract class MiddlewareClass<State> {
/// Middleware can optionally pass the original action or a modified action to
/// the next piece of middleware, or never call the next piece of middleware at
/// all.
typedef void NextDispatcher(dynamic action);
typedef dynamic NextDispatcher(dynamic action);

/// Creates a Redux store that holds the app state tree.
///
Expand Down Expand Up @@ -264,8 +264,7 @@ class Store<State> {
/// intercept actions, and can modify actions or stop them from passing
/// through to the reducer.
dynamic dispatch(dynamic action) {
_dispatchers[0](action);
return action;
return _dispatchers[0](action);
}

/// Closes down the Store so it will no longer be operational. Only use this
Expand Down
6 changes: 3 additions & 3 deletions lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,11 @@ class TypedMiddleware<State, Action> implements MiddlewareClass<State> {
TypedMiddleware(this.middleware);

@override
void call(Store<State> store, dynamic action, NextDispatcher next) {
dynamic call(Store<State> store, dynamic action, NextDispatcher next) {
if (action is Action) {
middleware(store, action, next);
return middleware(store, action, next);
} else {
next(action);
return next(action);
}
}
}
Expand Down
24 changes: 24 additions & 0 deletions test/middleware_test.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:async';
import 'package:redux/redux.dart';
import 'package:test/test.dart';

Expand Down Expand Up @@ -75,5 +76,28 @@ void main() {

expect(middleware1.counter, equals(2));
});

test('dispatch returns the value from middleware', () async {
final passthrough = PassThroughMiddleware<String>();
final thunk = ThunkMiddleware<String>();
Future<void> thunkAction(Store<String> store) async {
await Future<void>.delayed(Duration(milliseconds: 5));
store.dispatch("changed");
}

final store = Store<String>(
stringReducer,
initialState: 'hello',
middleware: [passthrough, thunk],
);

final awaitableAction = store.dispatch(thunkAction) as Future<void>;

// Did not change yet
expect(store.state, equals('hello'));
await awaitableAction;
// The effect has taken place
expect(store.state, equals('changed'));
});
});
}
21 changes: 19 additions & 2 deletions test/test_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ class StringReducer extends ReducerClass<String> {

class IncrementMiddleware extends MiddlewareClass<String> {
int counter = 0;
final _invocationsController =
StreamController<String>.broadcast(sync: true);
final _invocationsController = StreamController<String>.broadcast(sync: true);

Stream<String> get invocations => _invocationsController.stream;

Expand Down Expand Up @@ -72,6 +71,24 @@ class ExtraActionIfDispatchedIncrementMiddleware extends IncrementMiddleware {
}
}

class PassThroughMiddleware<State> implements MiddlewareClass<State> {
@override
dynamic call(Store<State> store, dynamic action, NextDispatcher next) {
return next(action);
}
}

class ThunkMiddleware<State> implements MiddlewareClass<State> {
@override
dynamic call(Store<State> store, dynamic action, NextDispatcher next) {
if (action is Function) {
return action(store);
} else {
return next(action);
}
}
}

class TestAction1 {}

class TestAction2 {}
Expand Down