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

Refactored Data Services

parent de23b1aa
Branches
Tags
No related merge requests found
Showing
with 422 additions and 392 deletions
......@@ -103,6 +103,7 @@
"ng2-translate": "4.2.0",
"preboot": "4.5.2",
"rxjs": "5.0.0-beta.12",
"ts-md5": "^1.2.0",
"webfontloader": "1.6.27",
"zone.js": "0.6.26"
},
......
import { EffectsModule } from "@ngrx/effects";
import { CollectionDataEffects } from "./data-services/collection/collection-data.effects";
import { ItemDataEffects } from "./data-services/item/item-data.effects";
import { CollectionDataEffects } from "./data-services/collection-data.effects";
import { ItemDataEffects } from "./data-services/item-data.effects";
export const coreEffects = [
EffectsModule.run(CollectionDataEffects),
......
......@@ -4,9 +4,9 @@ import { SharedModule } from "../shared/shared.module";
import { isNotEmpty } from "../shared/empty.util";
import { FooterComponent } from "./footer/footer.component";
import { DSpaceRESTv2Service } from "./dspace-rest-v2/dspace-rest-v2.service";
import { CollectionDataService } from "./data-services/collection/collection-data.service";
import { CacheService } from "./data-services/cache/cache.service";
import { ItemDataService } from "./data-services/item/item-data.service";
import { CollectionDataService } from "./data-services/collection-data.service";
import { ItemDataService } from "./data-services/item-data.service";
const IMPORTS = [
CommonModule,
......
import { combineReducers } from "@ngrx/store";
import {
CollectionDataState,
collectionDataReducer
} from "./data-services/collection/collection-data.reducer";
import { CacheState, cacheReducer } from "./data-services/cache/cache.reducer";
import { ItemDataState, itemDataReducer } from "./data-services/item/item-data.reducer";
import { dataReducer, DataState } from "./data-services/data.reducer";
export interface CoreState {
collectionData: CollectionDataState,
itemData: ItemDataState,
data: DataState,
cache: CacheState
}
export const reducers = {
collectionData: collectionDataReducer,
itemData: itemDataReducer,
data: dataReducer,
cache: cacheReducer
};
......
import { Injectable } from "@angular/core";
import { DataEffects } from "./data.effects";
import { Serializer } from "../serializer";
import { Collection } from "../shared/collection.model";
import { DSpaceRESTv2Serializer } from "../dspace-rest-v2/dspace-rest-v2.serializer";
import { CacheService } from "./cache/cache.service";
import { DSpaceRESTv2Service } from "../dspace-rest-v2/dspace-rest-v2.service";
import { Actions, Effect } from "@ngrx/effects";
import { DataFindAllRequestAction, DataFindByIDRequestAction } from "./data.actions";
import { CollectionDataService } from "./collection-data.service";
@Injectable()
export class CollectionDataEffects extends DataEffects<Collection> {
constructor(
actions$: Actions,
restApi: DSpaceRESTv2Service,
cache: CacheService,
dataService: CollectionDataService
) {
super(actions$, restApi, cache, dataService);
}
protected getFindAllEndpoint(action: DataFindAllRequestAction): string {
return '/collections';
}
protected getFindByIdEndpoint(action: DataFindByIDRequestAction): string {
return `/collections/${action.payload.resourceID}`;
}
protected getSerializer(): Serializer<Collection> {
return new DSpaceRESTv2Serializer(Collection);
}
@Effect() findAll$ = this.findAll;
@Effect() findById$ = this.findById;
}
import { Injectable, OpaqueToken } from "@angular/core";
import { Store } from "@ngrx/store";
import { DataService } from "./data.service";
import { Collection } from "../shared/collection.model";
import { CacheService } from "./cache/cache.service";
import { DataState } from "./data.reducer";
@Injectable()
export class CollectionDataService extends DataService<Collection> {
name = new OpaqueToken('CollectionDataService');
constructor(
store: Store<DataState>,
cache: CacheService
) {
super(store, cache);
}
}
import { Injectable } from "@angular/core";
import { Actions, Effect } from "@ngrx/effects";
import { Collection } from "../../shared/collection.model";
import { Observable } from "rxjs";
import {
CollectionFindMultipleActionTypes,
CollectionFindMultipleSuccessAction,
CollectionFindMultipleErrorAction
} from "./collection-find-multiple.actions";
import {
CollectionFindSingleActionTypes,
CollectionFindByIdSuccessAction,
CollectionFindByIdErrorAction
} from "./collection-find-single.actions";
import { DSpaceRESTV2Response } from "../../dspace-rest-v2/dspace-rest-v2-response.model";
import { DSpaceRESTv2Serializer } from "../../dspace-rest-v2/dspace-rest-v2.serializer";
import { DSpaceRESTv2Service } from "../../dspace-rest-v2/dspace-rest-v2.service";
import { CacheService } from "../cache/cache.service";
import { GlobalConfig } from "../../../../config";
@Injectable()
export class CollectionDataEffects {
constructor(
private actions$: Actions,
private restApi: DSpaceRESTv2Service,
private cache: CacheService
) {}
// TODO, results of a findall aren't retrieved from cache for now,
// because currently the cache is more of an object store. We need to move
// more towards memoization for things like this.
@Effect() findAll$ = this.actions$
.ofType(CollectionFindMultipleActionTypes.FIND_MULTI_REQUEST)
.switchMap(() => {
return this.restApi.get('/collections')
.map((data: DSpaceRESTV2Response) => new DSpaceRESTv2Serializer(Collection).deserializeArray(data))
.do((collections: Collection[]) => {
collections.forEach((collection) => {
this.cache.add(collection, GlobalConfig.cache.msToLive);
});
})
.map((collections: Array<Collection>) => collections.map(collection => collection.uuid))
.map((uuids: Array<string>) => new CollectionFindMultipleSuccessAction(uuids))
.catch((errorMsg: string) => Observable.of(new CollectionFindMultipleErrorAction(errorMsg)));
});
@Effect() findById$ = this.actions$
.ofType(CollectionFindSingleActionTypes.FIND_BY_ID_REQUEST)
.switchMap(action => {
return this.restApi.get(`/collections/${action.payload}`)
.map((data: DSpaceRESTV2Response) => new DSpaceRESTv2Serializer(Collection).deserialize(data))
.do((collection: Collection) => {
this.cache.add(collection, GlobalConfig.cache.msToLive);
})
.map((collection: Collection) => new CollectionFindByIdSuccessAction(collection.uuid))
.catch((errorMsg: string) => Observable.of(new CollectionFindByIdErrorAction(errorMsg)));
});
}
import { combineReducers } from "@ngrx/store";
import { CollectionFindMultipleState, findMultipleReducer } from "./collection-find-multiple.reducer";
import { CollectionFindSingleState, findSingleReducer } from "./collection-find-single.reducer";
export interface CollectionDataState {
findMultiple: CollectionFindMultipleState,
findSingle: CollectionFindSingleState
}
const reducers = {
findMultiple: findMultipleReducer,
findSingle: findSingleReducer
};
export function collectionDataReducer(state: any, action: any) {
return combineReducers(reducers)(state, action);
}
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { CollectionDataState } from "./collection-data.reducer";
import { Store } from "@ngrx/store";
import { Collection } from "../../shared/collection.model";
import { CollectionFindMultipleRequestAction } from "./collection-find-multiple.actions";
import { CollectionFindByIdRequestAction } from "./collection-find-single.actions";
import { CacheService } from "../cache/cache.service";
import 'rxjs/add/observable/forkJoin';
@Injectable()
export class CollectionDataService {
constructor(
private store: Store<CollectionDataState>,
private cache: CacheService
) { }
findAll(scopeID?: string): Observable<Collection[]> {
this.store.dispatch(new CollectionFindMultipleRequestAction(scopeID));
//get an observable of the IDs from the collectionData store
return this.store.select<Array<string>>('core', 'collectionData', 'findMultiple', 'collectionUUIDs')
.flatMap((collectionUUIDs: Array<string>) => {
// use those IDs to fetch the actual collection objects from the cache
return this.cache.getList<Collection>(collectionUUIDs);
});
}
findById(id: string): Observable<Collection> {
this.store.dispatch(new CollectionFindByIdRequestAction(id));
return this.store.select<string>('core', 'collectionData', 'findSingle', 'collectionUUID')
.flatMap((collectionUUID: string) => {
return this.cache.get<Collection>(collectionUUID);
});
}
}
import { Action } from "@ngrx/store";
import { type } from "../../../shared/ngrx/type";
import { PaginationOptions } from "../../shared/pagination-options.model";
import { SortOptions } from "../../shared/sort-options.model";
export const CollectionFindMultipleActionTypes = {
FIND_MULTI_REQUEST: type('dspace/core/data/collection/FIND_MULTI_REQUEST'),
FIND_MULTI_SUCCESS: type('dspace/core/data/collection/FIND_MULTI_SUCCESS'),
FIND_MULTI_ERROR: type('dspace/core/data/collection/FIND_MULTI_ERROR')
};
export class CollectionFindMultipleRequestAction implements Action {
type = CollectionFindMultipleActionTypes.FIND_MULTI_REQUEST;
payload: {
scopeID: string,
paginationOptions: PaginationOptions,
sortOptions: SortOptions
};
constructor(
scopeID?: string,
paginationOptions: PaginationOptions = new PaginationOptions(),
sortOptions: SortOptions = new SortOptions()
) {
this.payload = {
scopeID,
paginationOptions,
sortOptions
}
}
}
export class CollectionFindMultipleSuccessAction implements Action {
type = CollectionFindMultipleActionTypes.FIND_MULTI_SUCCESS;
payload: Array<string>;
constructor(collectionUUIDs: Array<string>) {
this.payload = collectionUUIDs;
}
}
export class CollectionFindMultipleErrorAction implements Action {
type = CollectionFindMultipleActionTypes.FIND_MULTI_ERROR;
payload: string;
constructor(errorMessage: string) {
this.payload = errorMessage;
}
}
export type CollectionFindMultipleAction
= CollectionFindMultipleRequestAction
| CollectionFindMultipleSuccessAction
| CollectionFindMultipleErrorAction;
import { PaginationOptions } from "../../shared/pagination-options.model";
import { SortOptions } from "../../shared/sort-options.model";
import {
CollectionFindMultipleAction,
CollectionFindMultipleActionTypes
} from "./collection-find-multiple.actions";
export interface CollectionFindMultipleState {
scopeID: string;
collectionUUIDs: Array<String>;
isLoading: boolean;
errorMessage: string;
paginationOptions: PaginationOptions;
sortOptions: SortOptions;
}
const initialState: CollectionFindMultipleState = {
scopeID: undefined,
collectionUUIDs: [],
isLoading: false,
errorMessage: undefined,
paginationOptions: undefined,
sortOptions: undefined
};
export const findMultipleReducer = (state = initialState, action: CollectionFindMultipleAction): CollectionFindMultipleState => {
switch (action.type) {
case CollectionFindMultipleActionTypes.FIND_MULTI_REQUEST: {
return Object.assign({}, state, {
scopeID: action.payload.scopeID,
collectionUUIDs: [],
isLoading: true,
errorMessage: undefined,
paginationOptions: action.payload.paginationOptions,
sortOptions: action.payload.sortOptions
});
}
case CollectionFindMultipleActionTypes.FIND_MULTI_SUCCESS: {
return Object.assign({}, state, {
isLoading: false,
collectionUUIDs: action.payload,
errorMessage: undefined
});
}
case CollectionFindMultipleActionTypes.FIND_MULTI_ERROR: {
return Object.assign({}, state, {
isLoading: false,
errorMessage: action.payload
});
}
default: {
return state;
}
}
};
import { Action } from "@ngrx/store";
import { type } from "../../../shared/ngrx/type";
import { Collection } from "../../shared/collection.model";
export const CollectionFindSingleActionTypes = {
FIND_BY_ID_REQUEST: type('dspace/core/data/collection/FIND_BY_ID_REQUEST'),
FIND_BY_ID_SUCCESS: type('dspace/core/data/collection/FIND_BY_ID_SUCCESS'),
FIND_BY_ID_ERROR: type('dspace/core/data/collection/FIND_BY_ID_ERROR')
};
export class CollectionFindByIdRequestAction implements Action {
type = CollectionFindSingleActionTypes.FIND_BY_ID_REQUEST;
payload: string;
constructor(requestID: string) {
this.payload = requestID;
}
}
export class CollectionFindByIdSuccessAction implements Action {
type = CollectionFindSingleActionTypes.FIND_BY_ID_SUCCESS;
payload: string;
constructor(collectionUUID: string) {
this.payload = collectionUUID;
}
}
export class CollectionFindByIdErrorAction implements Action {
type = CollectionFindSingleActionTypes.FIND_BY_ID_ERROR;
payload: string;
constructor(errorMessage: string) {
this.payload = errorMessage;
}
}
export type CollectionFindSingleAction
= CollectionFindByIdRequestAction
| CollectionFindByIdSuccessAction
| CollectionFindByIdErrorAction;
import { Collection } from "../../shared/collection.model";
import {
CollectionFindSingleAction,
CollectionFindSingleActionTypes
} from "./collection-find-single.actions";
export interface CollectionFindSingleState {
isLoading: boolean;
errorMessage: string;
requestedID: string;
collectionUUID: string;
}
const initialState: CollectionFindSingleState = {
isLoading: false,
errorMessage: undefined,
requestedID: undefined,
collectionUUID: undefined
};
export const findSingleReducer = (state = initialState, action: CollectionFindSingleAction): CollectionFindSingleState => {
switch (action.type) {
case CollectionFindSingleActionTypes.FIND_BY_ID_REQUEST: {
return Object.assign({}, state, {
isLoading: true,
errorMessage: undefined,
requestedID: action.payload
});
}
case CollectionFindSingleActionTypes.FIND_BY_ID_SUCCESS: {
return Object.assign({}, state, {
isLoading: false,
errorMessage: undefined,
collectionUUID: action.payload
});
}
case CollectionFindSingleActionTypes.FIND_BY_ID_ERROR: {
return Object.assign({}, state, {
isLoading: false,
errorMessage: action.payload
});
}
default: {
return state;
}
}
};
import { OpaqueToken } from "@angular/core";
import { Action } from "@ngrx/store";
import { type } from "../../shared/ngrx/type";
import { PaginationOptions } from "../shared/pagination-options.model";
import { SortOptions } from "../shared/sort-options.model";
export const DataActionTypes = {
FIND_BY_ID_REQUEST: type('dspace/core/data/FIND_BY_ID_REQUEST'),
FIND_ALL_REQUEST: type('dspace/core/data/FIND_ALL_REQUEST'),
SUCCESS: type('dspace/core/data/SUCCESS'),
ERROR: type('dspace/core/data/ERROR')
};
export class DataFindAllRequestAction implements Action {
type = DataActionTypes.FIND_ALL_REQUEST;
payload: {
key: string,
service: OpaqueToken,
scopeID: string,
paginationOptions: PaginationOptions,
sortOptions: SortOptions
};
constructor(
key: string,
service: OpaqueToken,
scopeID?: string,
paginationOptions: PaginationOptions = new PaginationOptions(),
sortOptions: SortOptions = new SortOptions()
) {
this.payload = {
key,
service,
scopeID,
paginationOptions,
sortOptions
}
}
}
export class DataFindByIDRequestAction implements Action {
type = DataActionTypes.FIND_BY_ID_REQUEST;
payload: {
key: string,
service: OpaqueToken,
resourceID: string
};
constructor(
key: string,
service: OpaqueToken,
resourceID: string
) {
this.payload = {
key,
service,
resourceID
}
}
}
export class DataSuccessAction implements Action {
type = DataActionTypes.SUCCESS;
payload: {
key: string,
resourceUUIDs: Array<string>
};
constructor(key: string, resourceUUIDs: Array<string>) {
this.payload = {
key,
resourceUUIDs
};
}
}
export class DataErrorAction implements Action {
type = DataActionTypes.ERROR;
payload: {
key: string,
errorMessage: string
};
constructor(key: string, errorMessage: string) {
this.payload = {
key,
errorMessage
};
}
}
export type DataAction
= DataFindAllRequestAction
| DataFindByIDRequestAction
| DataSuccessAction
| DataErrorAction;
import { Actions, Effect } from "@ngrx/effects";
import { Observable } from "rxjs";
import { DSpaceRESTV2Response } from "../dspace-rest-v2/dspace-rest-v2-response.model";
import { DSpaceRESTv2Service } from "../dspace-rest-v2/dspace-rest-v2.service";
import { CacheService } from "./cache/cache.service";
import { GlobalConfig } from "../../../config";
import { CacheableObject } from "./cache/cache.reducer";
import { Serializer } from "../serializer";
import {
DataActionTypes, DataFindAllRequestAction, DataSuccessAction,
DataErrorAction, DataFindByIDRequestAction, DataAction
} from "./data.actions";
import { DataService } from "./data.service";
export abstract class DataEffects<T extends CacheableObject> {
protected abstract getFindAllEndpoint(action: DataFindAllRequestAction): string;
protected abstract getFindByIdEndpoint(action: DataFindByIDRequestAction): string;
protected abstract getSerializer(): Serializer<T>;
constructor(
private actions$: Actions,
private restApi: DSpaceRESTv2Service,
private cache: CacheService,
private dataService: DataService<T>
) {}
// TODO, results of a findall aren't retrieved from cache for now,
// because currently the cache is more of an object store. We need to move
// more towards memoization for things like this.
protected findAll = this.actions$
.ofType(DataActionTypes.FIND_ALL_REQUEST)
.filter((action: DataFindAllRequestAction) => action.payload.service === this.dataService.name)
.switchMap((action: DataFindAllRequestAction) => {
//TODO scope, pagination, sorting -> when we know how that works in rest
return this.restApi.get(this.getFindAllEndpoint(action))
.map((data: DSpaceRESTV2Response) => this.getSerializer().deserializeArray(data))
.do((ts: T[]) => {
ts.forEach((t) => {
this.cache.add(t, GlobalConfig.cache.msToLive);
});
})
.map((ts: Array<T>) => ts.map(t => t.uuid))
.map((ids: Array<string>) => new DataSuccessAction(action.payload.key, ids))
.catch((errorMsg: string) => Observable.of(new DataErrorAction(action.payload.key, errorMsg)));
});
protected findById = this.actions$
.ofType(DataActionTypes.FIND_BY_ID_REQUEST)
.filter((action: DataFindAllRequestAction) => action.payload.service === this.dataService.name)
.switchMap((action: DataFindByIDRequestAction) => {
return this.restApi.get(this.getFindByIdEndpoint(action))
.map((data: DSpaceRESTV2Response) => this.getSerializer().deserialize(data))
.do((t: T) => {
this.cache.add(t, GlobalConfig.cache.msToLive);
})
.map((t: T) => new DataSuccessAction(action.payload.key, [t.uuid]))
.catch((errorMsg: string) => Observable.of(new DataErrorAction(action.payload.key, errorMsg)));
});
}
import { PaginationOptions } from "../shared/pagination-options.model";
import { SortOptions } from "../shared/sort-options.model";
import {
DataAction, DataActionTypes, DataFindAllRequestAction,
DataSuccessAction, DataErrorAction, DataFindByIDRequestAction
} from "./data.actions";
import { OpaqueToken } from "@angular/core";
export interface DataRequestState {
service: OpaqueToken
scopeID: string;
resourceID: string;
resourceUUIDs: Array<String>;
resourceType: String;
isLoading: boolean;
errorMessage: string;
paginationOptions: PaginationOptions;
sortOptions: SortOptions;
timeAdded: number;
msToLive: number;
}
export interface DataState {
[key: string]: DataRequestState
}
// Object.create(null) ensures the object has no default js properties (e.g. `__proto__`)
const initialState = Object.create(null);
export const dataReducer = (state = initialState, action: DataAction): DataState => {
switch (action.type) {
case DataActionTypes.FIND_ALL_REQUEST: {
return findAllRequest(state, <DataFindAllRequestAction> action);
}
case DataActionTypes.FIND_BY_ID_REQUEST: {
return findByIDRequest(state, <DataFindByIDRequestAction> action);
}
case DataActionTypes.SUCCESS: {
return success(state, <DataSuccessAction> action);
}
case DataActionTypes.ERROR: {
return error(state, <DataErrorAction> action);
}
default: {
return state;
}
}
};
function findAllRequest(state: DataState, action: DataFindAllRequestAction): DataState {
return Object.assign({}, state, {
[action.payload.key]: {
service: action.payload.service,
scopeID: action.payload.scopeID,
resourceUUIDs: [],
isLoading: true,
errorMessage: undefined,
paginationOptions: action.payload.paginationOptions,
sortOptions: action.payload.sortOptions
}
});
}
function findByIDRequest(state: DataState, action: DataFindByIDRequestAction): DataState {
return Object.assign({}, state, {
[action.payload.key]: {
service: action.payload.service,
resourceID: action.payload.resourceID,
resourceUUIDs: [],
isLoading: true,
errorMessage: undefined,
}
});
}
function success(state: DataState, action: DataSuccessAction): DataState {
return Object.assign({}, state, {
[action.payload.key]: Object.assign({}, state[action.payload.key], {
isLoading: false,
resourceUUIDs: action.payload.resourceUUIDs,
errorMessage: undefined
})
});
}
function error(state: DataState, action: DataErrorAction): DataState {
return Object.assign({}, state, {
[action.payload.key]: Object.assign({}, state[action.payload.key], {
isLoading: false,
errorMessage: action.payload.errorMessage
})
});
}
import { OpaqueToken } from "@angular/core";
import { Observable } from "rxjs";
import { Store } from "@ngrx/store";
import { CacheService } from "./cache/cache.service";
import { CacheableObject } from "./cache/cache.reducer";
import { DataState } from "./data.reducer";
import { DataFindAllRequestAction, DataFindByIDRequestAction } from "./data.actions";
import { ParamHash } from "../shared/param-hash";
import { isNotEmpty } from "../../shared/empty.util";
export abstract class DataService<T extends CacheableObject> {
abstract name: OpaqueToken;
constructor(
private store: Store<DataState>,
private cache: CacheService
) { }
findAll(scopeID?: string): Observable<Array<T>> {
const key = new ParamHash(this.name, 'findAll', scopeID).toString();
this.store.dispatch(new DataFindAllRequestAction(key, this.name, scopeID));
//get an observable of the IDs from the store
return this.store.select<Array<string>>('core', 'data', key, 'resourceUUIDs')
.flatMap((resourceUUIDs: Array<string>) => {
// use those IDs to fetch the actual objects from the cache
return this.cache.getList<T>(resourceUUIDs);
});
}
findById(id: string): Observable<T> {
const key = new ParamHash(this.name, 'findById', id).toString();
this.store.dispatch(new DataFindByIDRequestAction(key, this.name, id));
return this.store.select<Array<string>>('core', 'data', key, 'resourceUUIDs')
.flatMap((resourceUUIDs: Array<string>) => {
if(isNotEmpty(resourceUUIDs)) {
return this.cache.get<T>(resourceUUIDs[0]);
}
else {
return Observable.of(undefined);
}
});
}
}
import { Injectable } from "@angular/core";
import { DataEffects } from "./data.effects";
import { Serializer } from "../serializer";
import { Item } from "../shared/item.model";
import { DSpaceRESTv2Serializer } from "../dspace-rest-v2/dspace-rest-v2.serializer";
import { CacheService } from "./cache/cache.service";
import { DSpaceRESTv2Service } from "../dspace-rest-v2/dspace-rest-v2.service";
import { Actions, Effect } from "@ngrx/effects";
import { DataFindAllRequestAction, DataFindByIDRequestAction } from "./data.actions";
import { ItemDataService } from "./item-data.service";
@Injectable()
export class ItemDataEffects extends DataEffects<Item> {
constructor(
actions$: Actions,
restApi: DSpaceRESTv2Service,
cache: CacheService,
dataService: ItemDataService
) {
super(actions$, restApi, cache, dataService);
}
protected getFindAllEndpoint(action: DataFindAllRequestAction): string {
return '/items';
}
protected getFindByIdEndpoint(action: DataFindByIDRequestAction): string {
return `/items/${action.payload.resourceID}`;
}
protected getSerializer(): Serializer<Item> {
return new DSpaceRESTv2Serializer(Item);
}
@Effect() findAll$ = this.findAll;
@Effect() findById$ = this.findById;
}
import { Injectable, OpaqueToken } from "@angular/core";
import { Store } from "@ngrx/store";
import { DataService } from "./data.service";
import { Item } from "../shared/item.model";
import { CacheService } from "./cache/cache.service";
import { DataState } from "./data.reducer";
@Injectable()
export class ItemDataService extends DataService<Item> {
name = new OpaqueToken('ItemDataService');
constructor(
store: Store<DataState>,
cache: CacheService
) {
super(store, cache);
}
}
import { Injectable } from "@angular/core";
import { Actions, Effect } from "@ngrx/effects";
import { Item } from "../../shared/item.model";
import { Observable } from "rxjs";
import {
ItemFindMultipleActionTypes,
ItemFindMultipleSuccessAction,
ItemFindMultipleErrorAction
} from "./item-find-multiple.actions";
import {
ItemFindSingleActionTypes,
ItemFindByIdSuccessAction,
ItemFindByIdErrorAction
} from "./item-find-single.actions";
import { DSpaceRESTV2Response } from "../../dspace-rest-v2/dspace-rest-v2-response.model";
import { DSpaceRESTv2Serializer } from "../../dspace-rest-v2/dspace-rest-v2.serializer";
import { DSpaceRESTv2Service } from "../../dspace-rest-v2/dspace-rest-v2.service";
import { CacheService } from "../cache/cache.service";
import { GlobalConfig } from "../../../../config";
@Injectable()
export class ItemDataEffects {
constructor(
private actions$: Actions,
private restApi: DSpaceRESTv2Service,
private cache: CacheService
) {}
// TODO, results of a findall aren't retrieved from cache for now,
// because currently the cache is more of an object store. We need to move
// more towards memoization for things like this.
@Effect() findAll$ = this.actions$
.ofType(ItemFindMultipleActionTypes.FIND_MULTI_REQUEST)
.switchMap(() => {
return this.restApi.get('/items')
.map((data: DSpaceRESTV2Response) => new DSpaceRESTv2Serializer(Item).deserializeArray(data))
.do((items: Item[]) => {
items.forEach((item) => {
this.cache.add(item, GlobalConfig.cache.msToLive);
});
})
.map((items: Array<Item>) => items.map(item => item.uuid))
.map((uuids: Array<string>) => new ItemFindMultipleSuccessAction(uuids))
.catch((errorMsg: string) => Observable.of(new ItemFindMultipleErrorAction(errorMsg)));
});
@Effect() findById$ = this.actions$
.ofType(ItemFindSingleActionTypes.FIND_BY_ID_REQUEST)
.switchMap(action => {
return this.restApi.get(`/items/${action.payload}`)
.map((data: DSpaceRESTV2Response) => new DSpaceRESTv2Serializer(Item).deserialize(data))
.do((item: Item) => {
this.cache.add(item, GlobalConfig.cache.msToLive);
})
.map((item: Item) => new ItemFindByIdSuccessAction(item.uuid))
.catch((errorMsg: string) => Observable.of(new ItemFindByIdErrorAction(errorMsg)));
});
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment