From bfc9b8bcd4d2ce4de113e5eba812d8be980864df Mon Sep 17 00:00:00 2001 From: Josep M Sobrepere Date: Wed, 13 Jan 2021 14:56:06 +0100 Subject: [PATCH] fix(bind): the default value can be undefined --- .../src/bind/connectFactoryObservable.test.tsx | 17 +++++++++++++++++ .../core/src/bind/connectFactoryObservable.ts | 2 +- .../core/src/bind/connectObservable.test.tsx | 17 +++++++++++++++++ packages/core/src/bind/connectObservable.ts | 2 +- packages/core/src/bind/index.ts | 7 +++++-- packages/core/src/internal/share-latest.ts | 2 +- packages/core/src/shareLatest.ts | 3 ++- 7 files changed, 44 insertions(+), 6 deletions(-) diff --git a/packages/core/src/bind/connectFactoryObservable.test.tsx b/packages/core/src/bind/connectFactoryObservable.test.tsx index 8b2ab22..9f2e195 100644 --- a/packages/core/src/bind/connectFactoryObservable.test.tsx +++ b/packages/core/src/bind/connectFactoryObservable.test.tsx @@ -522,6 +522,23 @@ describe("connectFactoryObservable", () => { subscription.unsubscribe() }) + it("the defaultValue can be undefined", () => { + const number$ = new Subject() + const [useNumber] = bind(() => number$, undefined) + + const { result, unmount } = renderHook(() => useNumber()) + + expect(result.current).toBe(undefined) + + actHook(() => { + number$.next(5) + }) + + expect(result.current).toBe(5) + + unmount() + }) + it("if the observable hasn't emitted and a defaultValue is provided, it does not start suspense", () => { const number$ = new Subject() const [useNumber] = bind( diff --git a/packages/core/src/bind/connectFactoryObservable.ts b/packages/core/src/bind/connectFactoryObservable.ts index 670b195..1e6154f 100644 --- a/packages/core/src/bind/connectFactoryObservable.ts +++ b/packages/core/src/bind/connectFactoryObservable.ts @@ -45,8 +45,8 @@ export default function connectFactoryObservable( const sharedObservable$ = shareLatest( getObservable(...input), - false, defaultValue, + false, () => { cache.delete(keys) }, diff --git a/packages/core/src/bind/connectObservable.test.tsx b/packages/core/src/bind/connectObservable.test.tsx index c495a7e..4c17fbb 100644 --- a/packages/core/src/bind/connectObservable.test.tsx +++ b/packages/core/src/bind/connectObservable.test.tsx @@ -650,6 +650,23 @@ describe("connectObservable", () => { expect(errorCallback).toHaveBeenCalled() }) + it("the defaultValue can be undefined", () => { + const number$ = new Subject() + const [useNumber] = bind(number$, undefined) + + const { result, unmount } = renderHook(() => useNumber()) + + expect(result.current).toBe(undefined) + + act(() => { + number$.next(5) + }) + + expect(result.current).toBe(5) + + unmount() + }) + it("if the observable hasn't emitted and a defaultValue is provided, it does not start suspense", () => { const number$ = new Subject() const [useNumber] = bind(number$, 0) diff --git a/packages/core/src/bind/connectObservable.ts b/packages/core/src/bind/connectObservable.ts index d942e7e..b4cca34 100644 --- a/packages/core/src/bind/connectObservable.ts +++ b/packages/core/src/bind/connectObservable.ts @@ -21,7 +21,7 @@ export default function connectObservable( observable: Observable, defaultValue: T, ) { - const sharedObservable$ = shareLatest(observable, false, defaultValue) + const sharedObservable$ = shareLatest(observable, defaultValue, false) const useStaticObservable = () => useObservable(sharedObservable$) return [useStaticObservable, sharedObservable$] as const } diff --git a/packages/core/src/bind/index.ts b/packages/core/src/bind/index.ts index c7635bd..1fe8398 100644 --- a/packages/core/src/bind/index.ts +++ b/packages/core/src/bind/index.ts @@ -46,8 +46,11 @@ export function bind( defaultValue?: O, ): [(...args: A) => Exclude, (...args: A) => Observable] -export function bind(observable: any, defaultValue: any = EMPTY_VALUE) { +export function bind(observable: any, defaultValue: any) { return (typeof observable === "function" ? (connectFactoryObservable as any) - : connectObservable)(observable, defaultValue) + : connectObservable)( + observable, + arguments.length > 1 ? defaultValue : EMPTY_VALUE, + ) } diff --git a/packages/core/src/internal/share-latest.ts b/packages/core/src/internal/share-latest.ts index e2efcba..7acd943 100644 --- a/packages/core/src/internal/share-latest.ts +++ b/packages/core/src/internal/share-latest.ts @@ -5,8 +5,8 @@ import { SUSPENSE } from "../SUSPENSE" const shareLatest = ( source$: Observable, + defaultValue: T, shouldComplete = true, - defaultValue: T = EMPTY_VALUE, teardown = noop, ): BehaviorObservable => { let subject: Subject | null diff --git a/packages/core/src/shareLatest.ts b/packages/core/src/shareLatest.ts index 1d45f1e..e264ec8 100644 --- a/packages/core/src/shareLatest.ts +++ b/packages/core/src/shareLatest.ts @@ -1,5 +1,6 @@ import { Observable, MonoTypeOperatorFunction } from "rxjs" import internalShareLatest from "./internal/share-latest" +import { EMPTY_VALUE } from "./internal/empty-value" /** * A RxJS pipeable operator which shares and replays the latest emitted value. @@ -17,4 +18,4 @@ import internalShareLatest from "./internal/share-latest" */ export const shareLatest = (): MonoTypeOperatorFunction => ( source$: Observable, -) => internalShareLatest(source$) +) => internalShareLatest(source$, EMPTY_VALUE)