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
import { combineReducers } from "@ngrx/store";
import { ItemFindMultipleState, findMultipleReducer } from "./item-find-multiple.reducer";
import { ItemFindSingleState, findSingleReducer } from "./item-find-single.reducer";
export interface ItemDataState {
findMultiple: ItemFindMultipleState,
findSingle: ItemFindSingleState
}
const reducers = {
findMultiple: findMultipleReducer,
findSingle: findSingleReducer
};
export function itemDataReducer(state: any, action: any) {
return combineReducers(reducers)(state, action);
}
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
import { ItemDataState } from "./item-data.reducer";
import { Store } from "@ngrx/store";
import { Item } from "../../shared/item.model";
import { ItemFindMultipleRequestAction } from "./item-find-multiple.actions";
import { ItemFindByIdRequestAction } from "./item-find-single.actions";
import { CacheService } from "../cache/cache.service";
import 'rxjs/add/observable/forkJoin';
@Injectable()
export class ItemDataService {
constructor(
private store: Store<ItemDataState>,
private cache: CacheService
) { }
findAll(scopeID?: string): Observable<Item[]> {
this.store.dispatch(new ItemFindMultipleRequestAction(scopeID));
//get an observable of the IDs from the itemData store
return this.store.select<Array<string>>('core', 'itemData', 'findMultiple', 'itemUUIDs')
.flatMap((itemUUIDs: Array<string>) => {
// use those IDs to fetch the actual item objects from the cache
return this.cache.getList<Item>(itemUUIDs);
});
}
findById(id: string): Observable<Item> {
this.store.dispatch(new ItemFindByIdRequestAction(id));
return this.store.select<string>('core', 'itemData', 'findSingle', 'itemUUID')
.flatMap((itemUUID: string) => {
return this.cache.get<Item>(itemUUID);
});
}
}
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 ItemFindMultipleActionTypes = {
FIND_MULTI_REQUEST: type('dspace/core/data/item/FIND_MULTI_REQUEST'),
FIND_MULTI_SUCCESS: type('dspace/core/data/item/FIND_MULTI_SUCCESS'),
FIND_MULTI_ERROR: type('dspace/core/data/item/FIND_MULTI_ERROR')
};
export class ItemFindMultipleRequestAction implements Action {
type = ItemFindMultipleActionTypes.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 ItemFindMultipleSuccessAction implements Action {
type = ItemFindMultipleActionTypes.FIND_MULTI_SUCCESS;
payload: Array<string>;
constructor(itemUUIDs: Array<string>) {
this.payload = itemUUIDs;
}
}
export class ItemFindMultipleErrorAction implements Action {
type = ItemFindMultipleActionTypes.FIND_MULTI_ERROR;
payload: string;
constructor(errorMessage: string) {
this.payload = errorMessage;
}
}
export type ItemFindMultipleAction
= ItemFindMultipleRequestAction
| ItemFindMultipleSuccessAction
| ItemFindMultipleErrorAction;
import { PaginationOptions } from "../../shared/pagination-options.model";
import { SortOptions } from "../../shared/sort-options.model";
import {
ItemFindMultipleAction,
ItemFindMultipleActionTypes
} from "./item-find-multiple.actions";
export interface ItemFindMultipleState {
scopeID: string;
itemUUIDs: Array<String>;
isLoading: boolean;
errorMessage: string;
paginationOptions: PaginationOptions;
sortOptions: SortOptions;
}
const initialState: ItemFindMultipleState = {
scopeID: undefined,
itemUUIDs: [],
isLoading: false,
errorMessage: undefined,
paginationOptions: undefined,
sortOptions: undefined
};
export const findMultipleReducer = (state = initialState, action: ItemFindMultipleAction): ItemFindMultipleState => {
switch (action.type) {
case ItemFindMultipleActionTypes.FIND_MULTI_REQUEST: {
return Object.assign({}, state, {
scopeID: action.payload.scopeID,
itemUUIDs: [],
isLoading: true,
errorMessage: undefined,
paginationOptions: action.payload.paginationOptions,
sortOptions: action.payload.sortOptions
});
}
case ItemFindMultipleActionTypes.FIND_MULTI_SUCCESS: {
return Object.assign({}, state, {
isLoading: false,
itemUUIDs: action.payload,
errorMessage: undefined
});
}
case ItemFindMultipleActionTypes.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 { Item } from "../../shared/item.model";
export const ItemFindSingleActionTypes = {
FIND_BY_ID_REQUEST: type('dspace/core/data/item/FIND_BY_ID_REQUEST'),
FIND_BY_ID_SUCCESS: type('dspace/core/data/item/FIND_BY_ID_SUCCESS'),
FIND_BY_ID_ERROR: type('dspace/core/data/item/FIND_BY_ID_ERROR')
};
export class ItemFindByIdRequestAction implements Action {
type = ItemFindSingleActionTypes.FIND_BY_ID_REQUEST;
payload: string;
constructor(requestID: string) {
this.payload = requestID;
}
}
export class ItemFindByIdSuccessAction implements Action {
type = ItemFindSingleActionTypes.FIND_BY_ID_SUCCESS;
payload: string;
constructor(itemUUID: string) {
this.payload = itemUUID;
}
}
export class ItemFindByIdErrorAction implements Action {
type = ItemFindSingleActionTypes.FIND_BY_ID_ERROR;
payload: string;
constructor(errorMessage: string) {
this.payload = errorMessage;
}
}
export type ItemFindSingleAction
= ItemFindByIdRequestAction
| ItemFindByIdSuccessAction
| ItemFindByIdErrorAction;
import { Item } from "../../shared/item.model";
import {
ItemFindSingleAction,
ItemFindSingleActionTypes
} from "./item-find-single.actions";
export interface ItemFindSingleState {
isLoading: boolean;
errorMessage: string;
requestedID: string;
itemUUID: string;
}
const initialState: ItemFindSingleState = {
isLoading: false,
errorMessage: undefined,
requestedID: undefined,
itemUUID: undefined
};
export const findSingleReducer = (state = initialState, action: ItemFindSingleAction): ItemFindSingleState => {
switch (action.type) {
case ItemFindSingleActionTypes.FIND_BY_ID_REQUEST: {
return Object.assign({}, state, {
isLoading: true,
errorMessage: undefined,
requestedID: action.payload
});
}
case ItemFindSingleActionTypes.FIND_BY_ID_SUCCESS: {
return Object.assign({}, state, {
isLoading: false,
errorMessage: undefined,
itemUUID: action.payload
});
}
case ItemFindSingleActionTypes.FIND_BY_ID_ERROR: {
return Object.assign({}, state, {
isLoading: false,
errorMessage: action.payload
});
}
default: {
return state;
}
}
};
import { ParamHash } from "./param-hash";
describe("ParamHash", () => {
it("should return a hash for a set of parameters", () => {
const hash = new ParamHash('azerty', true, 23).toString();
expect(hash).not.toBeNull();
expect(hash).not.toBe('');
});
it("should work with both simple and complex objects as parameters", () => {
const hash = new ParamHash('azerty', true, 23, { "a": { "b": ['azerty', true] }, "c": 23 }).toString();
expect(hash).not.toBeNull();
expect(hash).not.toBe('');
});
it("should work with null or undefined as parameters", () => {
const hash1 = new ParamHash(undefined).toString();
const hash2 = new ParamHash(null).toString();
const hash3 = new ParamHash(undefined, null).toString();
expect(hash1).not.toBeNull();
expect(hash1).not.toBe('');
expect(hash2).not.toBeNull();
expect(hash2).not.toBe('');
expect(hash3).not.toBeNull();
expect(hash3).not.toBe('');
expect(hash1).not.toEqual(hash2);
expect(hash1).not.toEqual(hash3);
expect(hash2).not.toEqual(hash3);
});
it("should work if created without parameters", () => {
const hash1 = new ParamHash().toString();
const hash2 = new ParamHash().toString();
expect(hash1).not.toBeNull();
expect(hash1).not.toBe('');
expect(hash1).toEqual(hash2);
});
it("should create the same hash if created with the same set of parameters in the same order", () => {
const params = ['azerty', true, 23, { "a": { "b": ['azerty', true] }, "c": 23 }];
const hash1 = new ParamHash(...params).toString();
const hash2 = new ParamHash(...params).toString();
expect(hash1).toEqual(hash2);
});
it("should create a different hash if created with the same set of parameters in a different order", () => {
const params = ['azerty', true, 23, { "a": { "b": ['azerty', true] }, "c": 23 }];
const hash1 = new ParamHash(...params).toString();
const hash2 = new ParamHash(...params.reverse()).toString();
expect(hash1).not.toEqual(hash2);
});
});
import { Md5 } from "ts-md5/dist/md5";
/**
* Creates a hash of a set of parameters
*/
export class ParamHash {
private params: Array<any>;
constructor(...params) {
this.params = params;
}
/**
* Returns an md5 hash based on the
* params passed to the constructor
*
* If you hash the same set of params in the
* same order the hashes will be identical
*
* @return {string}
* an md5 hash
*/
toString(): string {
let hash = new Md5();
this.params.forEach((param) => {
if (param === Object(param)) {
hash.appendStr(JSON.stringify(param));
}
else {
hash.appendStr('' + param);
}
});
return hash.end().toString();
}
}
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