// 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>
230400cookie-checkTypescript datasource