Skip to content

Instantly share code, notes, and snippets.

@nite
Created March 4, 2021 11:51
Show Gist options
  • Select an option

  • Save nite/15ef0796e63906dc096ebef50613f4e5 to your computer and use it in GitHub Desktop.

Select an option

Save nite/15ef0796e63906dc096ebef50613f4e5 to your computer and use it in GitHub Desktop.

Revisions

  1. nite created this gist Mar 4, 2021.
    34 changes: 34 additions & 0 deletions toObservable.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,34 @@
    import { Observable } from 'rxjs';
    import { computed, IValueDidChange } from 'mobx';
    import isNil from 'lodash/isNil';
    import omit from 'lodash/omit';
    import { IEqualsComparer } from 'mobx/lib/internal';

    interface ToObservableOptions<T> {
    initial?: boolean;
    equals?: IEqualsComparer<T>;
    }

    /***
    * wrap function in mobx computed() and convert to observable
    *
    * @param observable - mobx observable property
    * @param options - initial: whether to fire an initial event if the property is non-empty
    */
    export function toObservable<T>(observable: () => T, options?: ToObservableOptions<T>): Observable<IValueDidChange<T>> {
    const optionsToUse: ToObservableOptions<T> = { initial: true, ...options };
    return new Observable((observer) => {
    const fireInitial = isNil(optionsToUse.initial) || optionsToUse.initial;
    const item = fireInitial && observable();
    if (item) {
    observer.next({
    newValue: item,
    object: item,
    type: 'update',
    oldValue: undefined,
    });
    }
    computed(observable, omit(optionsToUse, ['initial'])).observe((item) => observer.next(item));
    });
    }