diff --git a/src/store.js b/src/store.js
index 55edd9ea9..7c98c03ac 100644
--- a/src/store.js
+++ b/src/store.js
@@ -128,11 +128,19 @@ export class Store {
return
}
- this._actionSubscribers.forEach(sub => sub(action, this.state))
+ this._actionSubscribers
+ .filter(sub => sub.before)
+ .forEach(sub => sub.before(action, this.state))
- return entry.length > 1
+ const result = entry.length > 1
? Promise.all(entry.map(handler => handler(payload)))
: entry[0](payload)
+
+ result.then(() => this._actionSubscribers
+ .filter(sub => sub.after)
+ .forEach(sub => sub.after(action, this.state)))
+
+ return result
}
subscribe (fn) {
@@ -140,7 +148,8 @@ export class Store {
}
subscribeAction (fn) {
- return genericSubscribe(fn, this._actionSubscribers)
+ const subs = typeof fn === 'function' ? { before: fn } : fn
+ return genericSubscribe(subs, this._actionSubscribers)
}
watch (getter, cb, options) {
diff --git a/test/unit/modules.spec.js b/test/unit/modules.spec.js
index bc8fa2247..a776fb582 100644
--- a/test/unit/modules.spec.js
+++ b/test/unit/modules.spec.js
@@ -668,6 +668,37 @@ describe('Modules', () => {
store.state
)
})
+
+ it('action before/after subscribers', (done) => {
+ const beforeSpy = jasmine.createSpy()
+ const afterSpy = jasmine.createSpy()
+ const store = new Vuex.Store({
+ actions: {
+ [TEST]: () => Promise.resolve()
+ },
+ plugins: [
+ store => {
+ store.subscribeAction({
+ before: beforeSpy,
+ after: afterSpy
+ })
+ }
+ ]
+ })
+ store.dispatch(TEST, 2)
+ expect(beforeSpy).toHaveBeenCalledWith(
+ { type: TEST, payload: 2 },
+ store.state
+ )
+ expect(afterSpy).not.toHaveBeenCalled()
+ Vue.nextTick(() => {
+ expect(afterSpy).toHaveBeenCalledWith(
+ { type: TEST, payload: 2 },
+ store.state
+ )
+ done()
+ })
+ })
})
it('asserts a mutation should be a function', () => {
diff --git a/types/index.d.ts b/types/index.d.ts
index 70da30c1e..b5363cbc8 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -17,7 +17,7 @@ export declare class Store {
commit: Commit;
subscribe
(fn: (mutation: P, state: S) => any): () => void; - subscribeAction
(fn: (action: P, state: S) => any): () => void; + subscribeAction
(fn: SubscribeActionOptions
): () => void;
watch = (action: P, state: S) => any;
+
+export interface ActionSubscribersObject {
+ before?: ActionSubscriber ;
+ after?: ActionSubscriber ;
+}
+
+export type SubscribeActionOptions = ActionSubscriber | ActionSubscribersObject ;
+
export interface DispatchOptions {
root?: boolean;
}
diff --git a/types/test/index.ts b/types/test/index.ts
index 0253e5df8..0befc7fe9 100644
--- a/types/test/index.ts
+++ b/types/test/index.ts
@@ -39,12 +39,41 @@ namespace StoreInstance {
state.value;
});
- store.subscribeAction((mutation, state) => {
- mutation.type;
- mutation.payload;
+ store.subscribeAction((action, state) => {
+ action.type;
+ action.payload;
state.value;
});
+ store.subscribeAction({
+ before(action, state) {
+ action.type;
+ action.payload;
+ state.value;
+ }
+ });
+
+ store.subscribeAction({
+ before(action, state) {
+ action.type;
+ action.payload;
+ state.value;
+ },
+ after(action, state) {
+ action.type;
+ action.payload;
+ state.value;
+ }
+ });
+
+ store.subscribeAction({
+ after(action, state) {
+ action.type;
+ action.payload;
+ state.value;
+ }
+ });
+
store.replaceState({ value: 10 });
}