mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
introduced remotedata selector
This commit is contained in:
@@ -6,6 +6,7 @@ import { CacheableObject } from "../cache/object-cache.reducer";
|
|||||||
import { ParamHash } from "../shared/param-hash";
|
import { ParamHash } from "../shared/param-hash";
|
||||||
import { isNotEmpty } from "../../shared/empty.util";
|
import { isNotEmpty } from "../../shared/empty.util";
|
||||||
import { GenericConstructor } from "../shared/generic-constructor";
|
import { GenericConstructor } from "../shared/generic-constructor";
|
||||||
|
import { RemoteData } from "./remote-data";
|
||||||
|
|
||||||
export abstract class DataService<T extends CacheableObject> {
|
export abstract class DataService<T extends CacheableObject> {
|
||||||
abstract serviceName: OpaqueToken;
|
abstract serviceName: OpaqueToken;
|
||||||
@@ -16,20 +17,28 @@ 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();
|
const key = new ParamHash(this.serviceName, 'findAll', scopeID).toString();
|
||||||
return this.requestCache.findAll(key, this.serviceName, scopeID)
|
const requestCacheObs = this.requestCache.findAll(key, this.serviceName, scopeID);
|
||||||
//get an observable of the IDs from the RequestCache
|
return new RemoteData(
|
||||||
|
requestCacheObs.map(entry => entry.isLoading).distinctUntilChanged(),
|
||||||
|
requestCacheObs.map(entry => entry.errorMessage).distinctUntilChanged(),
|
||||||
|
requestCacheObs
|
||||||
.map(entry => entry.resourceUUIDs)
|
.map(entry => entry.resourceUUIDs)
|
||||||
.flatMap((resourceUUIDs: Array<string>) => {
|
.flatMap((resourceUUIDs: Array<string>) => {
|
||||||
// use those IDs to fetch the actual objects from the ObjectCache
|
// use those IDs to fetch the actual objects from the ObjectCache
|
||||||
return this.objectCache.getList<T>(resourceUUIDs, this.modelType);
|
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();
|
const key = new ParamHash(this.serviceName, 'findById', id).toString();
|
||||||
return this.requestCache.findById(key, this.serviceName, id)
|
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)
|
.map(entry => entry.resourceUUIDs)
|
||||||
.flatMap((resourceUUIDs: Array<string>) => {
|
.flatMap((resourceUUIDs: Array<string>) => {
|
||||||
if (isNotEmpty(resourceUUIDs)) {
|
if (isNotEmpty(resourceUUIDs)) {
|
||||||
@@ -38,7 +47,8 @@ export abstract class DataService<T extends CacheableObject> {
|
|||||||
else {
|
else {
|
||||||
return Observable.of(undefined);
|
return Observable.of(undefined);
|
||||||
}
|
}
|
||||||
});
|
}).distinctUntilChanged()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
75
src/app/core/data-services/remote-data.ts
Normal file
75
src/app/core/data-services/remote-data.ts
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user