Skip to content

Commit 8c7a56a

Browse files
anbratenlukashass
andauthored
feat: expose unloading function and only auto-unload inside components (#67)
* Update useFind.ts * improve loading / unloading of composition * fix lint * fix tests * do not expose load function for now * readd disableUnloadingEventHandlers option * use unload instead of unmount for events Co-authored-by: Lukas Hass <[email protected]>
1 parent a0c9d63 commit 8c7a56a

File tree

4 files changed

+83
-36
lines changed

4 files changed

+83
-36
lines changed

src/useFind.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Application, FeathersService, Params, ServiceMethods } from '@feathersjs/feathers';
22
import sift from 'sift';
3-
import { onBeforeUnmount, onMounted, Ref, ref, watch } from 'vue';
3+
import { getCurrentInstance, onBeforeUnmount, Ref, ref, watch } from 'vue';
44

55
import { getId, ServiceModel, ServiceTypes } from './utils';
66

@@ -69,6 +69,7 @@ function loadServiceEventHandlers<
6969
export type UseFind<T> = {
7070
data: Ref<T[]>;
7171
isLoading: Ref<boolean>;
72+
unload: () => void;
7273
};
7374

7475
// TODO: workaround, since extracting the type with ReturnType<T> does not work for generic functions. See https://stackoverflow.com/a/52964723
@@ -108,26 +109,21 @@ export default <CustomApplication extends Application>(feathers: CustomApplicati
108109
isLoading.value = false;
109110
};
110111

111-
watch(params, () => {
112-
void find();
113-
});
114-
115-
const connectListener = () => {
112+
const load = () => {
116113
void find();
117114
};
118115

119-
feathers.on('connect', connectListener);
116+
const unload = () => {
117+
unloadEventHandlers();
118+
feathers.off('connect', load);
119+
};
120120

121-
onMounted(async () => {
122-
await find();
123-
});
121+
watch(params, load, { immediate: true });
122+
feathers.on('connect', load);
124123

125-
if (!disableUnloadingEventHandlers) {
126-
onBeforeUnmount(() => {
127-
unloadEventHandlers();
128-
feathers.off('connect', connectListener);
129-
});
124+
if (disableUnloadingEventHandlers === false && getCurrentInstance()) {
125+
onBeforeUnmount(unload);
130126
}
131127

132-
return { data, isLoading };
128+
return { data, isLoading, unload };
133129
};

src/useGet.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Application, FeathersService, Id, Params, ServiceMethods } from '@feathersjs/feathers';
2-
import { onBeforeUnmount, onMounted, Ref, ref, watch } from 'vue';
2+
import { getCurrentInstance, onBeforeUnmount, Ref, ref, watch } from 'vue';
33

44
import { getId, ServiceModel, ServiceTypes } from './utils';
55

@@ -56,6 +56,7 @@ function loadServiceEventHandlers<
5656
export type UseGet<T> = {
5757
data: Ref<T | undefined>;
5858
isLoading: Ref<boolean>;
59+
unload: () => void;
5960
};
6061

6162
// TODO: workaround, since extracting the type with ReturnType<T> does not work for generic functions. See https://stackoverflow.com/a/52964723
@@ -94,26 +95,21 @@ export default <CustomApplication extends Application>(feathers: CustomApplicati
9495
isLoading.value = false;
9596
};
9697

97-
watch(_id, async () => {
98-
await get();
99-
});
100-
101-
const connectListener = () => {
98+
const load = () => {
10299
void get();
103100
};
104101

105-
feathers.on('connect', connectListener);
102+
const unload = () => {
103+
unloadEventHandlers();
104+
feathers.off('connect', load);
105+
};
106106

107-
onMounted(async () => {
108-
await get();
109-
});
107+
watch(_id, load, { immediate: true });
108+
feathers.on('connect', load);
110109

111-
if (!disableUnloadingEventHandlers) {
112-
onBeforeUnmount(() => {
113-
unloadEventHandlers();
114-
feathers.off('connect', connectListener);
115-
});
110+
if (disableUnloadingEventHandlers === false && getCurrentInstance()) {
111+
onBeforeUnmount(unload);
116112
}
117113

118-
return { isLoading, data };
114+
return { isLoading, data, unload };
119115
};

test/useFind.test.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ describe('Find composition', () => {
606606
expect(findComposition && findComposition.data.value).not.toContainEqual(testModel);
607607
});
608608

609-
it('should unmount the event handlers', () => {
609+
it('should unload the event handlers', () => {
610610
expect.assertions(7);
611611

612612
// given
@@ -640,7 +640,7 @@ describe('Find composition', () => {
640640
expect(serviceOff).toHaveBeenCalledWith('removed', expect.anything());
641641
});
642642

643-
it('should not unmount the event handlers when desired', () => {
643+
it('should not unload the event handlers when desired', () => {
644644
expect.assertions(3);
645645

646646
// given
@@ -671,5 +671,32 @@ describe('Find composition', () => {
671671
expect(feathersOff).not.toHaveBeenCalled();
672672
expect(serviceOff).not.toHaveBeenCalled();
673673
});
674+
675+
it('should unload the event handlers when desired', () => {
676+
expect.assertions(3);
677+
678+
// given
679+
const serviceOff = jest.fn();
680+
const feathersOff = jest.fn();
681+
const feathersMock = {
682+
service: () => ({
683+
find: jest.fn(),
684+
on: jest.fn(),
685+
off: serviceOff,
686+
}),
687+
on: jest.fn(),
688+
off: feathersOff,
689+
} as unknown as Application;
690+
const useFind = useFindOriginal(feathersMock);
691+
const findComposition = useFind('testModels', ref({ paginate: false, query: {} }));
692+
693+
// when
694+
findComposition.unload();
695+
696+
// then
697+
expect(findComposition).toBeTruthy();
698+
expect(feathersOff).toHaveBeenCalledTimes(1);
699+
expect(serviceOff).toHaveBeenCalledTimes(4); // unload of: created, updated, patched, removed events
700+
});
674701
});
675702
});

test/useGet.test.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ describe('Get composition', () => {
486486
expect(getComposition && getComposition.data.value).toStrictEqual(testModel);
487487
});
488488

489-
it('should unmount the event handlers', () => {
489+
it('should unload the event handlers', () => {
490490
expect.assertions(7);
491491

492492
// given
@@ -519,7 +519,8 @@ describe('Get composition', () => {
519519
expect(serviceOff).toHaveBeenCalledWith('patched', expect.anything());
520520
expect(serviceOff).toHaveBeenCalledWith('removed', expect.anything());
521521
});
522-
it('should not unmount the event handlers when desired', () => {
522+
523+
it('should not unload the event handlers when desired', () => {
523524
expect.assertions(3);
524525

525526
// given
@@ -548,5 +549,32 @@ describe('Get composition', () => {
548549
expect(feathersOff).not.toHaveBeenCalled();
549550
expect(serviceOff).not.toHaveBeenCalled();
550551
});
552+
553+
it('should unload the event handlers when desired', () => {
554+
expect.assertions(3);
555+
556+
// given
557+
const serviceOff = jest.fn();
558+
const feathersOff = jest.fn();
559+
const feathersMock = {
560+
service: () => ({
561+
get: jest.fn(),
562+
on: jest.fn(),
563+
off: serviceOff,
564+
}),
565+
on: jest.fn(),
566+
off: feathersOff,
567+
} as unknown as Application;
568+
const useGet = useGetOriginal(feathersMock);
569+
const getComposition = useGet('testModels', ref(testModel._id), ref());
570+
571+
// when
572+
getComposition.unload();
573+
574+
// then
575+
expect(getComposition).toBeTruthy();
576+
expect(feathersOff).toHaveBeenCalledTimes(1);
577+
expect(serviceOff).toHaveBeenCalledTimes(4); // unload of: created, updated, patched, removed events
578+
});
551579
});
552580
});

0 commit comments

Comments
 (0)