Skip to content

Commit

Permalink
♻️ ionicFetch with ref or fun
Browse files Browse the repository at this point in the history
  • Loading branch information
trydofor committed Dec 20, 2024
1 parent bdbb396 commit bc04d02
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 18 deletions.
24 changes: 20 additions & 4 deletions layers/common/tests/typed-fetcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,30 @@
import { fetchTypedData, fetchTypedDataAsync } from '../utils/typed-fetcher';

describe('fetchTypedData', () => {
it('should call loading with status error', () => {
const loadingSpy = vi.fn();
const catchesSpy = vi.fn();

const fetching = () => {
throw new Error('Test Error');
};

const result = fetchTypedResult(fetching, { loading: loadingSpy, catches: catchesSpy });

expect(loadingSpy).toHaveBeenNthCalledWith(1, 1);
expect(loadingSpy).toHaveBeenNthCalledWith(2, 2);
expect(catchesSpy).toHaveBeenNthCalledWith(1, new Error('Test Error'));
expect(result).toEqual({ success: false });
});

it('should call loading with true and false', () => {
const loadingSpy = vi.fn();
const fetching = { success: true, data: 'test-data' } as DataResult<string>;

fetchTypedData(fetching, { loading: loadingSpy });

expect(loadingSpy).toHaveBeenNthCalledWith(1, true);
expect(loadingSpy).toHaveBeenNthCalledWith(2, false);
expect(loadingSpy).toHaveBeenNthCalledWith(1, 1);
expect(loadingSpy).toHaveBeenNthCalledWith(2, 0);
});

it('should return data when fetching succeeds', () => {
Expand Down Expand Up @@ -57,8 +73,8 @@ describe('fetchTypedDataAsync', () => {

await fetchTypedDataAsync(fetching, { loading: loadingSpy });

expect(loadingSpy).toHaveBeenNthCalledWith(1, true);
expect(loadingSpy).toHaveBeenNthCalledWith(2, false);
expect(loadingSpy).toHaveBeenNthCalledWith(1, 1);
expect(loadingSpy).toHaveBeenNthCalledWith(2, 0);
});

it('should return data when fetching succeeds asynchronously', async () => {
Expand Down
27 changes: 18 additions & 9 deletions layers/common/utils/typed-fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
export type TypedFetchOptions = {
/**
* true if loading(1), false if done(0) or error(2)
*/
export type LoadingStatus = 1 | 0 | 2;

export type TypedFetchOptions = {
/**
* @param status - true if loading, false if done
* @param status - true if loading(1), false if done(0) or error(2)
*/
loading?: Ref<boolean> | ((status: boolean) => void);
loading?: Ref<boolean> | ((status: LoadingStatus) => void);
/**
* when DataResult.success is false
* @param message - DataResult.message
Expand All @@ -17,12 +22,12 @@
catches?: (err: any) => void;
};

function _doLoading(status: boolean, loading?: Ref<boolean> | ((status: boolean) => void)): void {
function _doLoading(status: LoadingStatus, loading?: Ref<boolean> | ((status: LoadingStatus) => void)): void {
if (typeof loading === 'function') {
loading(status);
}
else if (loading != null) {
loading.value = status;
loading.value = status === 1;
}
}

Expand Down Expand Up @@ -81,17 +86,19 @@ export function fetchTypedResult<T>(
fetching: DataResult<T> | (() => DataResult<T>),
options: TypedFetchOptions = {},
): DataResult<T> {
_doLoading(true, options.loading);
_doLoading(1, options.loading);

let sts: LoadingStatus = 0;
try {
const result = typeof fetching === 'function' ? fetching() : fetching;
return _doResult(options.failure, result);
}
catch (err) {
sts = 2;
_doError(err, options.catches);
}
finally {
_doLoading(false, options.loading);
_doLoading(sts, options.loading);
}

return { success: false };
Expand All @@ -106,17 +113,19 @@ export async function fetchTypedResultAsync<T>(
fetching: Promise<DataResult<T>> | (() => Promise<DataResult<T>>),
options: TypedFetchOptions = {},
): Promise<DataResult<T>> {
_doLoading(true, options.loading);
_doLoading(1, options.loading);

let sts: LoadingStatus = 0;
try {
const result = await (typeof fetching === 'function' ? fetching() : fetching);
return _doResult(options.failure, result);
}
catch (err) {
sts = 2;
_doError(err, options.catches);
}
finally {
_doLoading(false, options.loading);
_doLoading(sts, options.loading);
}

return { success: false };
Expand Down
10 changes: 5 additions & 5 deletions layers/mobile/utils/ionic-fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { loadingController, alertController } from '@ionic/vue';
import { fetchTypedResultAsync } from '&razor-common/utils/typed-fetcher';
import { fetchTypedResultAsync, type LoadingStatus } from '&razor-common/utils/typed-fetcher';

function _failure(message?: string, code?: string) {
alertController.create({
Expand Down Expand Up @@ -27,7 +27,7 @@ function _catches(err: any) {
* @param fetching - Promise of DataResult
* @param loading - Ref of boolean instead of using loadingController
*/
export async function ionicFetchDataAsync<T>(fetching: Promise<DataResult<T>>, loading?: Ref<boolean>): Promise<T | null> {
export async function ionicFetchDataAsync<T>(fetching: Promise<DataResult<T>>, loading?: Ref<boolean> | ((status: LoadingStatus) => void)): Promise<T | null> {
const result = await ionicFetchResultAsync(fetching, loading);
return result.data ?? null;
}
Expand All @@ -37,7 +37,7 @@ export async function ionicFetchDataAsync<T>(fetching: Promise<DataResult<T>>, l
* @param fetching - Promise of DataResult
* @param loading - Ref of boolean instead of using loadingController
*/
export async function ionicFetchResultAsync<T>(fetching: Promise<DataResult<T>>, loading?: Ref<boolean>): Promise<DataResult<T>> {
export async function ionicFetchResultAsync<T>(fetching: Promise<DataResult<T>>, loading?: Ref<boolean> | ((status: LoadingStatus) => void)): Promise<DataResult<T>> {
if (loading) {
return fetchTypedResultAsync(fetching, {
loading,
Expand All @@ -52,8 +52,8 @@ export async function ionicFetchResultAsync<T>(fetching: Promise<DataResult<T>>,
duration: 5000,
});

const _loading = (bool: boolean) => {
if (bool) {
const _loading = (sts: LoadingStatus) => {
if (sts == 1) {
ui.present();
}
else {
Expand Down
5 changes: 5 additions & 0 deletions vitest.workspace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// for vscode plugin
export default [
'./layers/common/vitest.config.ts',
'./layers/mobile/vitest.config.ts',
];

0 comments on commit bc04d02

Please sign in to comment.