diff --git a/hooks/useLoadData/useLoadData.test.ts b/hooks/useLoadData/useLoadData.test.ts index 53977f6..5a3f17a 100644 --- a/hooks/useLoadData/useLoadData.test.ts +++ b/hooks/useLoadData/useLoadData.test.ts @@ -442,4 +442,13 @@ describe('useLoadData', () => { expect(getSuccess).toHaveBeenCalledTimes(2); expect(getSuccess).toHaveBeenCalledWith('b'); }); + + it('should treat a thenable object as a Promise', async () => { + const getThenableSuccess = jest.fn(() => ({then: (resolve: any) => resolve(successResult)})); + + const {result} = renderHook(() => useLoadData(getThenableSuccess)); + expect(result.current.isInProgress).toBe(true); + await waitFor(() => expect(result.current.isInProgress).toBe(false)); + expect(result.current.result).toBe(successResult); + }); }); diff --git a/hooks/useLoadData/useLoadData.ts b/hooks/useLoadData/useLoadData.ts index b6c6e85..bf4eb9e 100644 --- a/hooks/useLoadData/useLoadData.ts +++ b/hooks/useLoadData/useLoadData.ts @@ -1,5 +1,5 @@ import {useEffect, useState, useMemo} from 'react'; -import {ApiResponse, RetryResponse, ApiResponseBase, OptionalDependency, DependencyBase} from '../../types'; +import {ApiResponse, RetryResponse, ApiResponseBase, OptionalDependency, DependencyBase, Promisable} from '../../types'; import {FetchData, NotUndefined} from './types'; @@ -30,6 +30,15 @@ function unboxApiResponse(arg: ApiResponse | T): T { } } +function isPromise(promisable: Promisable): promisable is Promise { + /* + Simply checking promisable instanceof Promise is not sufficient. + Certain environments do not use native promises. Checking for promisable + to be thenable is a more comprehensive and conclusive test. + */ + return promisable && typeof promisable === 'object' && 'then' in promisable && typeof promisable.then === 'function'; +} + export interface LoadDataConfig { fetchWhenDepsChange?: boolean; maxRetryCount?: number; @@ -186,7 +195,7 @@ export function useLoadData( } }, [counter, localFetchWhenDepsChange]); - const nonPromiseResult = initialPromise.res instanceof Promise ? undefined : initialPromise.res; + const nonPromiseResult = isPromise(initialPromise.res) ? undefined : initialPromise.res; const initialData = data || nonPromiseResult; // Initialize our pending data to one of three possible states: diff --git a/package.json b/package.json index 99385ef..e60a986 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@optum/react-hooks", - "version": "1.0.4", + "version": "1.0.5-next.1", "description": "A reusable set of React hooks", "repository": "https://github.com/Optum/react-hooks", "license": "Apache 2.0",