Typescript datasource

Date: 2019-07-02
// tslint:disable-next-line: import-blacklist
import {  Observable, BehaviorSubject, Subject } from "rxjs";
import { map } from "rxjs/operators";

export interface IDataSource<T> {
    readonly data: Observable<T[]>;
    readonly loading: Observable<boolean>;
    load(): PromiseLike<T[]>;
    reload(): PromiseLike<T[]>;
    filter(filterFn: (obj: any) => boolean);
}
export class DataSource<T> implements IDataSource<T> {
    private _loading = new BehaviorSubject<boolean>(false);
    private _dataArr: T[];
    private _data: Subject<T[]>;
    private _dataPromise: PromiseLike<T[]>;
    private _filterFn: (obj: any) => boolean;
    constructor(private _dataFn: () => PromiseLike<T[]>) {
        this._filterFn = (obj: any) => true;
        this._data = new BehaviorSubject<T[]>([]);
    }
    async load(reload: boolean = false) {
        if (!this._dataPromise || reload) {
            return this.reload();
        }
        return await this._dataPromise;
    }
    async reload() {
        this._loading.next(true);
        this._dataPromise = this._dataFn();
        Promise.resolve(this._dataPromise)
            .then((d) => {
                this._dataArr = d;
                this._data.next(d);
                return d;
            }).finally(() => this._loading.next(false));
        return await this._dataPromise;
    }
    get data(): Observable<T[]> {
        return this._data.pipe(map((arr: T[]) => Array.from(arr).filter(this._filterFn)));
    }
    get loading(): Observable<boolean> {
        return this._loading.asObservable();
    }
    filter(filterFn: (obj: any) => boolean) {
        if (!filterFn) {
            filterFn = (obj: any) => true;
        }
        this._filterFn = filterFn;
        if (this._dataArr) {
            this._data.next(this._dataArr);
        }
    }
}
// usage
        this.dataSource = new DataSource<IDebtorOrder>(async () => {
            const completeOrderHistory = await appDomain.IRequestStoreDebtorOrder.getLastOrders(3);
            return completeOrderHistory;
        });
        this.dataSource.load();
<ng-container *ngFor="let order of dataSource.data | async">
        <app-order-history-item [debtorOrder]="order"></app-order-history-item>
    </ng-container>
23040cookie-checkTypescript datasource