Last active
February 8, 2020 15:40
-
-
Save laat/ccb70e170c06d6d8718452925566205b to your computer and use it in GitHub Desktop.
rxjs nullable modad-ish
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ajax } from "rxjs/ajax"; | |
import { BehaviorSubject, combineLatest } from "rxjs"; | |
import { Nullable as N } from "./Nullable"; | |
import { NullableArray as NA } from "./NullableArray"; | |
interface Data { | |
next: string; | |
} | |
const hostname = new BehaviorSubject<null | string>(null); | |
const data$ = hostname.pipe( | |
N.map(host => `https://${host}/data.json`), | |
N.switchMap(url => ajax.getJSON<Data>(url)) | |
); | |
const next$ = combineLatest([data$, hostname]).pipe( | |
NA.map(([data, host]) => `https://${host}${data.next}`), | |
N.switchMap(url => ajax.getJSON<Data>(url)) | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Observable, of } from "rxjs"; | |
import { map, switchMap } from "rxjs/operators"; | |
export class Nullable { | |
static isNotNull<T>(v: T): v is NonNullable<T> { | |
return v != null; | |
} | |
static bind = <T, R>( | |
project: (value: NonNullable<T>, index: number) => R | |
) => (value: T, index: number): R | null => | |
Nullable.isNotNull(value) ? project(value, index) : null; | |
static bindObservable = <T, R>( | |
project: (value: NonNullable<T>, index: number) => Observable<R> | |
) => (value: T, index: number): Observable<R | null> => | |
Nullable.isNotNull(value) ? project(value, index) : of(null); | |
static map = <T, R>( | |
project: (value: NonNullable<T>, index: number) => R, | |
thisArg?: any | |
) => map(Nullable.bind(project), thisArg); | |
static switchMap = <T, R>( | |
project: (x: NonNullable<T>, i: number) => Observable<R>, | |
thisArg?: any | |
) => | |
switchMap<T, Observable<R | null>>( | |
Nullable.bindObservable(project), | |
thisArg | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Nullable } from "./Nullable"; | |
import { Observable, of } from "rxjs"; | |
import { map, switchMap } from "rxjs/operators"; | |
export type NonNullableArray<T extends ReadonlyArray<any>> = { | |
[K in keyof T]: T[K] extends infer V ? NonNullable<V> : never; | |
}; | |
export class NullableArray { | |
static hasNoNull = <T extends ReadonlyArray<any>>( | |
xs: readonly T[] | |
): xs is NonNullableArray<T> => xs.every(Nullable.isNotNull); | |
static bind = <T extends ReadonlyArray<any>, R>( | |
project: (value: NonNullableArray<T>, index: number) => R | |
) => (value: T, index: number): R | null => | |
NullableArray.hasNoNull<T>(value) ? project(value, index) : null; | |
static bindObservable = <T extends ReadonlyArray<any>, R>( | |
project: (value: NonNullableArray<T>, index: number) => Observable<R> | |
) => (value: T, index: number): Observable<R | null> => | |
NullableArray.hasNoNull<T>(value) ? project(value, index) : of(null); | |
static map = <T extends ReadonlyArray<any>, R>( | |
project: (value: NonNullableArray<T>, index: number) => R, | |
thisArg?: any | |
) => map(NullableArray.bind(project), thisArg); | |
static switchMap = <T extends ReadonlyArray<any>, R>( | |
project: (value: NonNullableArray<T>, index: number) => Observable<R>, | |
thisArg?: any | |
) => | |
switchMap<T, Observable<R | null>>( | |
NullableArray.bindObservable(project), | |
thisArg | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment