Skip to content
Snippets Groups Projects
Commit a62c8d62 authored by Art Lowel's avatar Art Lowel
Browse files

introduced remotedata selector

parent a4579e54
No related branches found
No related tags found
No related merge requests found
......@@ -6,6 +6,7 @@ import { CacheableObject } from "../cache/object-cache.reducer";
import { ParamHash } from "../shared/param-hash";
import { isNotEmpty } from "../../shared/empty.util";
import { GenericConstructor } from "../shared/generic-constructor";
import { RemoteData } from "./remote-data";
export abstract class DataService<T extends CacheableObject> {
abstract serviceName: OpaqueToken;
......@@ -16,29 +17,38 @@ export abstract class DataService<T extends CacheableObject> {
}
findAll(scopeID?: string): Observable<Array<T>> {
findAll(scopeID?: string): RemoteData<Array<T>> {
const key = new ParamHash(this.serviceName, 'findAll', scopeID).toString();
return this.requestCache.findAll(key, this.serviceName, scopeID)
//get an observable of the IDs from the RequestCache
.map(entry => entry.resourceUUIDs)
.flatMap((resourceUUIDs: Array<string>) => {
// use those IDs to fetch the actual objects from the ObjectCache
return this.objectCache.getList<T>(resourceUUIDs, this.modelType);
});
const requestCacheObs = this.requestCache.findAll(key, this.serviceName, scopeID);
return new RemoteData(
requestCacheObs.map(entry => entry.isLoading).distinctUntilChanged(),
requestCacheObs.map(entry => entry.errorMessage).distinctUntilChanged(),
requestCacheObs
.map(entry => entry.resourceUUIDs)
.flatMap((resourceUUIDs: Array<string>) => {
// use those IDs to fetch the actual objects from the ObjectCache
return this.objectCache.getList<T>(resourceUUIDs, this.modelType);
}).distinctUntilChanged()
);
}
findById(id: string): Observable<T> {
findById(id: string): RemoteData<T> {
const key = new ParamHash(this.serviceName, 'findById', id).toString();
return this.requestCache.findById(key, this.serviceName, id)
.map(entry => entry.resourceUUIDs)
.flatMap((resourceUUIDs: Array<string>) => {
if(isNotEmpty(resourceUUIDs)) {
return this.objectCache.get<T>(resourceUUIDs[0], this.modelType);
}
else {
return Observable.of(undefined);
}
});
const requestCacheObs = this.requestCache.findById(key, this.serviceName, id);
return new RemoteData(
requestCacheObs.map(entry => entry.isLoading).distinctUntilChanged(),
requestCacheObs.map(entry => entry.errorMessage).distinctUntilChanged(),
requestCacheObs
.map(entry => entry.resourceUUIDs)
.flatMap((resourceUUIDs: Array<string>) => {
if (isNotEmpty(resourceUUIDs)) {
return this.objectCache.get<T>(resourceUUIDs[0], this.modelType);
}
else {
return Observable.of(undefined);
}
}).distinctUntilChanged()
);
}
}
import { Observable } from "rxjs";
import { hasValue } from "../../shared/empty.util";
export enum RemoteDataState {
//TODO RequestPending will never happen: implement it in the store & DataEffects.
RequestPending,
ResponsePending,
Failed,
Success
}
/**
* A class to represent the state of
*/
export class RemoteData<T> {
constructor(
private storeLoading: Observable<boolean>,
public errorMessage: Observable<string>,
public payload: Observable<T>
) {
}
get state(): Observable<RemoteDataState> {
return Observable.combineLatest(
this.storeLoading,
this.errorMessage.map(msg => hasValue(msg)),
(storeLoading, hasMsg) => {
if (storeLoading) {
return RemoteDataState.ResponsePending
}
else if (hasMsg) {
return RemoteDataState.Failed
}
else {
return RemoteDataState.Success
}
}
).distinctUntilChanged();
}
get isRequestPending(): Observable<boolean> {
return this.state
.map(state => state == RemoteDataState.RequestPending)
.distinctUntilChanged();
}
get isResponsePending(): Observable<boolean> {
return this.state
.map(state => state == RemoteDataState.ResponsePending)
.distinctUntilChanged();
}
get isLoading(): Observable<boolean> {
return this.state
.map(state => {
return state == RemoteDataState.RequestPending
|| state === RemoteDataState.ResponsePending
})
.distinctUntilChanged();
}
get hasFailed(): Observable<boolean> {
return this.state
.map(state => state == RemoteDataState.Failed)
.distinctUntilChanged();
}
get hasSucceeded(): Observable<boolean> {
return this.state
.map(state => state == RemoteDataState.Success)
.distinctUntilChanged();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment