Skip to content

Commit 76818c1

Browse files
Wael Al-Sallamiyyx990803
Wael Al-Sallami
authored andcommitted
Action before and after subscribers (#1115)
* allow action subscribers to specify before/after hooks (#1098) Action subscribers are called before the action by default. This allows them to specify before and after subscribers where the after subscriber is called when the action resolves * add test cases for the new before/after action subscribers (#1098) make sure that the before subscriber is called before the action, while the after subscriber is called after it resolves * Replace Promise initialization with shorter form (#1098) * Update subscribeAction type declaration and add type tests (#1098) Generalize subscribeAction's type declaration to accept both a function or an object and add type tests for that
1 parent da22a6e commit 76818c1

File tree

4 files changed

+85
-7
lines changed

4 files changed

+85
-7
lines changed

src/store.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -129,19 +129,28 @@ export class Store {
129129
return
130130
}
131131

132-
this._actionSubscribers.forEach(sub => sub(action, this.state))
132+
this._actionSubscribers
133+
.filter(sub => sub.before)
134+
.forEach(sub => sub.before(action, this.state))
133135

134-
return entry.length > 1
136+
const result = entry.length > 1
135137
? Promise.all(entry.map(handler => handler(payload)))
136138
: entry[0](payload)
139+
140+
result.then(() => this._actionSubscribers
141+
.filter(sub => sub.after)
142+
.forEach(sub => sub.after(action, this.state)))
143+
144+
return result
137145
}
138146

139147
subscribe (fn) {
140148
return genericSubscribe(fn, this._subscribers)
141149
}
142150

143151
subscribeAction (fn) {
144-
return genericSubscribe(fn, this._actionSubscribers)
152+
const subs = typeof fn === 'function' ? { before: fn } : fn
153+
return genericSubscribe(subs, this._actionSubscribers)
145154
}
146155

147156
watch (getter, cb, options) {

test/unit/modules.spec.js

+31
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,37 @@ describe('Modules', () => {
668668
store.state
669669
)
670670
})
671+
672+
it('action before/after subscribers', (done) => {
673+
const beforeSpy = jasmine.createSpy()
674+
const afterSpy = jasmine.createSpy()
675+
const store = new Vuex.Store({
676+
actions: {
677+
[TEST]: () => Promise.resolve()
678+
},
679+
plugins: [
680+
store => {
681+
store.subscribeAction({
682+
before: beforeSpy,
683+
after: afterSpy
684+
})
685+
}
686+
]
687+
})
688+
store.dispatch(TEST, 2)
689+
expect(beforeSpy).toHaveBeenCalledWith(
690+
{ type: TEST, payload: 2 },
691+
store.state
692+
)
693+
expect(afterSpy).not.toHaveBeenCalled()
694+
Vue.nextTick(() => {
695+
expect(afterSpy).toHaveBeenCalledWith(
696+
{ type: TEST, payload: 2 },
697+
store.state
698+
)
699+
done()
700+
})
701+
})
671702
})
672703

673704
it('asserts a mutation should be a function', () => {

types/index.d.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export declare class Store<S> {
1919
commit: Commit;
2020

2121
subscribe<P extends MutationPayload>(fn: (mutation: P, state: S) => any): () => void;
22-
subscribeAction<P extends ActionPayload>(fn: (action: P, state: S) => any): () => void;
22+
subscribeAction<P extends ActionPayload>(fn: SubscribeActionOptions<P, S>): () => void;
2323
watch<T>(getter: (state: S, getters: any) => T, cb: (value: T, oldValue: T) => void, options?: WatchOptions): () => void;
2424

2525
registerModule<T>(path: string, module: Module<T, S>, options?: ModuleOptions): void;
@@ -69,6 +69,15 @@ export interface ActionPayload extends Payload {
6969
payload: any;
7070
}
7171

72+
export type ActionSubscriber<P, S> = (action: P, state: S) => any;
73+
74+
export interface ActionSubscribersObject<P, S> {
75+
before?: ActionSubscriber<P, S>;
76+
after?: ActionSubscriber<P, S>;
77+
}
78+
79+
export type SubscribeActionOptions<P, S> = ActionSubscriber<P, S> | ActionSubscribersObject<P, S>;
80+
7281
export interface DispatchOptions {
7382
root?: boolean;
7483
}

types/test/index.ts

+32-3
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,41 @@ namespace StoreInstance {
3939
state.value;
4040
});
4141

42-
store.subscribeAction((mutation, state) => {
43-
mutation.type;
44-
mutation.payload;
42+
store.subscribeAction((action, state) => {
43+
action.type;
44+
action.payload;
4545
state.value;
4646
});
4747

48+
store.subscribeAction({
49+
before(action, state) {
50+
action.type;
51+
action.payload;
52+
state.value;
53+
}
54+
});
55+
56+
store.subscribeAction({
57+
before(action, state) {
58+
action.type;
59+
action.payload;
60+
state.value;
61+
},
62+
after(action, state) {
63+
action.type;
64+
action.payload;
65+
state.value;
66+
}
67+
});
68+
69+
store.subscribeAction({
70+
after(action, state) {
71+
action.type;
72+
action.payload;
73+
state.value;
74+
}
75+
});
76+
4877
store.replaceState({ value: 10 });
4978
}
5079

0 commit comments

Comments
 (0)