Skip to content

Commit c771a3e

Browse files
Add the possibility to disable unloading of event handlers onUnmount (#7)
Adds parameter object with property `disableUnloadingEventHandlers` to `useFind` to disable automatic unloading of feathers service event listeners on component unmount. This makes it possible to change the component and keep the event listeners attached and therefore enable the use of singleton patterns to load data. Co-authored-by: Anbraten <[email protected]>
1 parent 494324c commit c771a3e

File tree

4 files changed

+85
-18
lines changed

4 files changed

+85
-18
lines changed

src/useFind.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ function loadServiceEventHandlers<
88
CustomApplication extends Application,
99
T extends keyof ServiceTypes<CustomApplication>,
1010
M,
11-
>(
12-
service: FeathersService<CustomApplication, ServiceTypes<CustomApplication>[T]>,
13-
params: Ref<Params>,
14-
data: Ref<M[]>,
11+
>(
12+
service: FeathersService<CustomApplication, ServiceTypes<CustomApplication>[T]>,
13+
params: Ref<Params>,
14+
data: Ref<M[]>,
1515
): () => void {
1616
const onCreated = (item: M): void => {
1717
// ignore items which are not matching the query
@@ -67,7 +67,7 @@ export type UseFind<T> = {
6767
export type UseFindFunc<CustomApplication> = <
6868
T extends keyof ServiceTypes<CustomApplication>,
6969
M = ServiceModel<CustomApplication, T>,
70-
>(
70+
>(
7171
serviceName: T,
7272
params?: Ref<Params>,
7373
) => UseFind<M>;
@@ -76,6 +76,7 @@ export default <CustomApplication extends Application>(feathers: CustomApplicati
7676
<T extends keyof ServiceTypes<CustomApplication>, M = ServiceModel<CustomApplication, T>>(
7777
serviceName: T,
7878
params: Ref<Params> = ref({ paginate: false, query: {} }),
79+
{ disableUnloadingEventHandlers } = { disableUnloadingEventHandlers: false },
7980
): UseFind<M> => {
8081
// type cast is fine here (source: https://github.com/vuejs/vue-next/issues/2136#issuecomment-693524663)
8182
const data = ref<M[]>([]) as Ref<M[]>;
@@ -110,10 +111,12 @@ export default <CustomApplication extends Application>(feathers: CustomApplicati
110111
await find();
111112
});
112113

113-
onBeforeUnmount(() => {
114-
unloadEventHandlers();
115-
feathers.off('connect', connectListener);
116-
});
114+
if (!disableUnloadingEventHandlers) {
115+
onBeforeUnmount(() => {
116+
unloadEventHandlers();
117+
feathers.off('connect', connectListener);
118+
});
119+
}
117120

118121
return { data, isLoading };
119122
};

src/useGet.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ function loadServiceEventHandlers<
77
CustomApplication extends Application,
88
T extends keyof ServiceTypes<CustomApplication>,
99
M,
10-
>(
11-
service: FeathersService<CustomApplication, ServiceTypes<CustomApplication>[T]>,
12-
_id: Ref<Id | undefined>,
13-
data: Ref<M | undefined>,
10+
>(
11+
service: FeathersService<CustomApplication, ServiceTypes<CustomApplication>[T]>,
12+
_id: Ref<Id | undefined>,
13+
data: Ref<M | undefined>,
1414
): () => void {
1515
const onCreated = (item: M): void => {
1616
if (_id.value === getId(item)) {
@@ -54,7 +54,7 @@ export type UseGet<T> = {
5454
export type UseGetFunc<CustomApplication> = <
5555
T extends keyof ServiceTypes<CustomApplication>,
5656
M = ServiceModel<CustomApplication, T>,
57-
>(
57+
>(
5858
serviceName: T,
5959
_id: Ref<Id | undefined>,
6060
) => UseGet<M>;
@@ -63,6 +63,7 @@ export default <CustomApplication extends Application>(feathers: CustomApplicati
6363
<T extends keyof ServiceTypes<CustomApplication>, M = ServiceModel<CustomApplication, T>>(
6464
serviceName: T,
6565
_id: Ref<Id | undefined>,
66+
{ disableUnloadingEventHandlers } = { disableUnloadingEventHandlers: false },
6667
): UseGet<M> => {
6768
const data = ref<M>();
6869
const isLoading = ref(false);
@@ -97,10 +98,12 @@ export default <CustomApplication extends Application>(feathers: CustomApplicati
9798
await get();
9899
});
99100

100-
onBeforeUnmount(() => {
101-
unloadEventHandlers();
102-
feathers.off('connect', connectListener);
103-
});
101+
if (!disableUnloadingEventHandlers) {
102+
onBeforeUnmount(() => {
103+
unloadEventHandlers();
104+
feathers.off('connect', connectListener);
105+
});
106+
}
104107

105108
return { isLoading, data };
106109
};

test/useFind.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,5 +466,37 @@ describe('Find composition', () => {
466466
expect(serviceOff).toHaveBeenCalledWith('patched', expect.anything());
467467
expect(serviceOff).toHaveBeenCalledWith('removed', expect.anything());
468468
});
469+
470+
it('should not unmount the event handlers when desired', () => {
471+
expect.assertions(3);
472+
473+
// given
474+
const serviceOff = jest.fn();
475+
const feathersOff = jest.fn();
476+
const feathersMock = {
477+
service: () => ({
478+
find: jest.fn(),
479+
on: jest.fn(),
480+
off: serviceOff,
481+
}),
482+
on: jest.fn(),
483+
off: feathersOff,
484+
} as unknown as Application;
485+
const useFind = useFindOriginal(feathersMock);
486+
let findComposition = null as UseFind<TestModel> | null;
487+
const wrapper = mountComposition(() => {
488+
findComposition = useFind('testModels', ref({ paginate: false, query: {} }), {
489+
disableUnloadingEventHandlers: true,
490+
});
491+
});
492+
493+
// when
494+
wrapper.unmount();
495+
496+
// then
497+
expect(findComposition).toBeTruthy();
498+
expect(feathersOff).not.toHaveBeenCalled();
499+
expect(serviceOff).not.toHaveBeenCalled();
500+
});
469501
});
470502
});

test/useGet.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,5 +518,34 @@ describe('Get composition', () => {
518518
expect(serviceOff).toHaveBeenCalledWith('patched', expect.anything());
519519
expect(serviceOff).toHaveBeenCalledWith('removed', expect.anything());
520520
});
521+
it('should not unmount the event handlers when desired', () => {
522+
expect.assertions(3);
523+
524+
// given
525+
const serviceOff = jest.fn();
526+
const feathersOff = jest.fn();
527+
const feathersMock = {
528+
service: () => ({
529+
get: jest.fn(),
530+
on: jest.fn(),
531+
off: serviceOff,
532+
}),
533+
on: jest.fn(),
534+
off: feathersOff,
535+
} as unknown as Application;
536+
const useGet = useGetOriginal(feathersMock);
537+
let getComposition = null as UseGet<TestModel> | null;
538+
const wrapper = mountComposition(() => {
539+
getComposition = useGet('testModels', ref(testModel._id), { disableUnloadingEventHandlers: true });
540+
});
541+
542+
// when
543+
wrapper.unmount();
544+
545+
// then
546+
expect(getComposition).toBeTruthy();
547+
expect(feathersOff).not.toHaveBeenCalled();
548+
expect(serviceOff).not.toHaveBeenCalled();
549+
});
521550
});
522551
});

0 commit comments

Comments
 (0)