Skip to content

Commit 26ecc03

Browse files
authored
Merge pull request DSpace#2897 from 4Science/DURACOM-247
Fixes for DSpace#2891 DSpace#2889
2 parents 10db33b + b2f94b5 commit 26ecc03

14 files changed

+161
-169
lines changed

src/app/core/cache/builders/link.service.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ class TestModel implements HALResource {
3737
successor?: TestModel;
3838
}
3939

40-
const mockDataServiceMap: any = {
41-
[TEST_MODEL.value]: () => import('../../../shared/testing/test-data-service.mock').then(m => m.TestDataService),
42-
};
40+
const mockDataServiceMap: any = new Map([
41+
[TEST_MODEL.value, () => import('../../../shared/testing/test-data-service.mock').then(m => m.TestDataService)],
42+
]);
4343

4444
let testDataService: TestDataService;
4545

src/app/core/cache/builders/link.service.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {
22
Inject,
33
Injectable,
4-
InjectionToken,
54
Injector,
65
} from '@angular/core';
76
import {
@@ -25,7 +24,7 @@ import { FollowLinkConfig } from '../../../shared/utils/follow-link-config.model
2524
import { HALDataService } from '../../data/base/hal-data-service.interface';
2625
import { PaginatedList } from '../../data/paginated-list.model';
2726
import { RemoteData } from '../../data/remote-data';
28-
import { lazyService } from '../../lazy-service';
27+
import { lazyDataService } from '../../lazy-data-service';
2928
import { GenericConstructor } from '../../shared/generic-constructor';
3029
import { HALResource } from '../../shared/hal-resource.model';
3130
import {
@@ -43,7 +42,7 @@ export class LinkService {
4342

4443
constructor(
4544
protected injector: Injector,
46-
@Inject(APP_DATA_SERVICES_MAP) private map: InjectionToken<LazyDataServicesMap>,
45+
@Inject(APP_DATA_SERVICES_MAP) private map: LazyDataServicesMap,
4746
@Inject(LINK_DEFINITION_FACTORY) private getLinkDefinition: <T extends HALResource>(source: GenericConstructor<T>, linkName: keyof T['_links']) => LinkDefinition<T>,
4847
@Inject(LINK_DEFINITION_MAP_FACTORY) private getLinkDefinitions: <T extends HALResource>(source: GenericConstructor<T>) => Map<keyof T['_links'], LinkDefinition<T>>,
4948
) {
@@ -73,7 +72,7 @@ export class LinkService {
7372
public resolveLinkWithoutAttaching<T extends HALResource, U extends HALResource>(model, linkToFollow: FollowLinkConfig<T>): Observable<RemoteData<U | PaginatedList<U>>> {
7473
const matchingLinkDef = this.getLinkDefinition(model.constructor, linkToFollow.name);
7574
if (hasValue(matchingLinkDef)) {
76-
const lazyProvider$: Observable<HALDataService<any>> = lazyService(this.map[matchingLinkDef.resourceType.value], this.injector);
75+
const lazyProvider$: Observable<HALDataService<any>> = lazyDataService(this.map, matchingLinkDef.resourceType.value, this.injector);
7776
return lazyProvider$.pipe(
7877
switchMap((provider: HALDataService<any>) => {
7978
const link = model._links[matchingLinkDef.linkName];

src/app/core/data-services-map.ts

Lines changed: 68 additions & 70 deletions
Large diffs are not rendered by default.

src/app/core/data/request.effects.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
map,
1414
mergeMap,
1515
take,
16+
withLatestFrom,
1617
} from 'rxjs/operators';
1718

1819
import {
@@ -25,6 +26,7 @@ import { ParsedResponse } from '../cache/response.models';
2526
import { DSpaceSerializer } from '../dspace-rest/dspace.serializer';
2627
import { DspaceRestService } from '../dspace-rest/dspace-rest.service';
2728
import { RawRestResponse } from '../dspace-rest/raw-rest-response.model';
29+
import { XSRFService } from '../xsrf/xsrf.service';
2830
import {
2931
RequestActionTypes,
3032
RequestErrorAction,
@@ -35,6 +37,7 @@ import {
3537
import { RequestService } from './request.service';
3638
import { RequestEntry } from './request-entry.model';
3739
import { RequestError } from './request-error.model';
40+
import { RestRequestMethod } from './rest-request-method';
3841
import { RestRequestWithResponseParser } from './rest-request-with-response-parser.model';
3942

4043
@Injectable()
@@ -48,7 +51,11 @@ export class RequestEffects {
4851
);
4952
}),
5053
filter((entry: RequestEntry) => hasValue(entry)),
51-
map((entry: RequestEntry) => entry.request),
54+
withLatestFrom(this.xsrfService.tokenInitialized$),
55+
// If it's a GET request, or we have an XSRF token, dispatch it immediately
56+
// Otherwise wait for the XSRF token first
57+
filter(([entry, tokenInitialized]: [RequestEntry, boolean]) => entry.request.method === RestRequestMethod.GET || tokenInitialized === true),
58+
map(([entry, tokenInitialized]: [RequestEntry, boolean]) => entry.request),
5259
mergeMap((request: RestRequestWithResponseParser) => {
5360
let body = request.body;
5461
if (isNotEmpty(request.body) && !request.isMultipart) {
@@ -89,6 +96,7 @@ export class RequestEffects {
8996
private restApi: DspaceRestService,
9097
private injector: Injector,
9198
protected requestService: RequestService,
99+
protected xsrfService: XSRFService,
92100
) { }
93101

94102
}

src/app/core/data/request.service.spec.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
getTestScheduler,
1818
} from 'jasmine-marbles';
1919
import {
20-
BehaviorSubject,
2120
EMPTY,
2221
Observable,
2322
of as observableOf,
@@ -34,7 +33,6 @@ import { ObjectCacheService } from '../cache/object-cache.service';
3433
import { coreReducers } from '../core.reducers';
3534
import { CoreState } from '../core-state.model';
3635
import { UUIDService } from '../shared/uuid.service';
37-
import { XSRFService } from '../xsrf/xsrf.service';
3836
import {
3937
RequestConfigureAction,
4038
RequestExecuteAction,
@@ -62,7 +60,6 @@ describe('RequestService', () => {
6260
let uuidService: UUIDService;
6361
let store: Store<CoreState>;
6462
let mockStore: MockStore<CoreState>;
65-
let xsrfService: XSRFService;
6663

6764
const testUUID = '5f2a0d2a-effa-4d54-bd54-5663b960f9eb';
6865
const testHref = 'https://rest.api/endpoint/selfLink';
@@ -108,16 +105,11 @@ describe('RequestService', () => {
108105
store = TestBed.inject(Store);
109106
mockStore = store as MockStore<CoreState>;
110107
mockStore.setState(initialState);
111-
xsrfService = {
112-
tokenInitialized$: new BehaviorSubject(false),
113-
} as XSRFService;
114108

115109
service = new RequestService(
116110
objectCache,
117111
uuidService,
118112
store,
119-
xsrfService,
120-
undefined,
121113
);
122114
serviceAsAny = service as any;
123115
});

src/app/core/data/request.service.ts

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,12 @@ import { ObjectCacheService } from '../cache/object-cache.service';
3434
import { CommitSSBAction } from '../cache/server-sync-buffer.actions';
3535
import { coreSelector } from '../core.selectors';
3636
import { CoreState } from '../core-state.model';
37-
import {
38-
IndexState,
39-
MetaIndexState,
40-
} from '../index/index.reducer';
37+
import { IndexState } from '../index/index.reducer';
4138
import {
4239
getUrlWithoutEmbedParams,
4340
requestIndexSelector,
4441
} from '../index/index.selectors';
4542
import { UUIDService } from '../shared/uuid.service';
46-
import { XSRFService } from '../xsrf/xsrf.service';
4743
import {
4844
RequestConfigureAction,
4945
RequestExecuteAction,
@@ -169,9 +165,7 @@ export class RequestService {
169165

170166
constructor(private objectCache: ObjectCacheService,
171167
private uuidService: UUIDService,
172-
private store: Store<CoreState>,
173-
protected xsrfService: XSRFService,
174-
private indexStore: Store<MetaIndexState>) {
168+
private store: Store<CoreState>) {
175169
}
176170

177171
generateRequestId(): string {
@@ -455,17 +449,7 @@ export class RequestService {
455449
private dispatchRequest(request: RestRequest) {
456450
asapScheduler.schedule(() => {
457451
this.store.dispatch(new RequestConfigureAction(request));
458-
// If it's a GET request, or we have an XSRF token, dispatch it immediately
459-
if (request.method === RestRequestMethod.GET || this.xsrfService.tokenInitialized$.getValue() === true) {
460-
this.store.dispatch(new RequestExecuteAction(request.uuid));
461-
} else {
462-
// Otherwise wait for the XSRF token first
463-
this.xsrfService.tokenInitialized$.pipe(
464-
find((hasInitialized: boolean) => hasInitialized === true),
465-
).subscribe(() => {
466-
this.store.dispatch(new RequestExecuteAction(request.uuid));
467-
});
468-
}
452+
this.store.dispatch(new RequestExecuteAction(request.uuid));
469453
});
470454
}
471455

src/app/core/lazy-data-service.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {
2+
Injector,
3+
Type,
4+
} from '@angular/core';
5+
import {
6+
defer,
7+
Observable,
8+
} from 'rxjs';
9+
10+
import { LazyDataServicesMap } from '../../config/app-config.interface';
11+
import { HALDataService } from './data/base/hal-data-service.interface';
12+
13+
/**
14+
* Loads a service lazily. The service is loaded when the observable is subscribed to.
15+
*
16+
* @param dataServicesMap A map of promises returning the data services to load
17+
* @param key The key of the service
18+
* @param injector The injector to use to load the service. If not provided, the current injector is used.
19+
* @returns An observable of the service.
20+
*
21+
* @example
22+
* ```ts
23+
* const dataService$ = lazyDataService({ 'data-service': () => import('./data-service').then((m) => m.MyService)}, 'data-service', this.injector);
24+
* or
25+
* const dataService$ = lazyDataService({'data-service': () => import('./data-service')}, 'data-service', this.injector);
26+
* ```
27+
*/
28+
export function lazyDataService<T>(
29+
dataServicesMap: LazyDataServicesMap,
30+
key: string,
31+
injector: Injector,
32+
): Observable<T> {
33+
return defer(() => {
34+
if (dataServicesMap.has(key) && typeof dataServicesMap.get(key) === 'function') {
35+
const loader: () => Promise<Type<HALDataService<any>> | { default: HALDataService<any> }> = dataServicesMap.get(key);
36+
return loader()
37+
.then((serviceOrDefault) => {
38+
if ('default' in serviceOrDefault) {
39+
return injector!.get(serviceOrDefault.default);
40+
}
41+
return injector!.get(serviceOrDefault);
42+
})
43+
.catch((error) => {
44+
throw error;
45+
});
46+
} else {
47+
return null;
48+
}
49+
});
50+
}

src/app/core/lazy-service.ts

Lines changed: 0 additions & 40 deletions
This file was deleted.

src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ const REINSTATE_BTN = 'reinstate';
3838
const SAVE_BTN = 'save';
3939
const DISCARD_BTN = 'discard';
4040

41-
const mockDataServiceMap: any = {
42-
[ITEM.value]: () => import('../../shared/testing/test-data-service.mock').then(m => m.TestDataService),
43-
};
41+
const mockDataServiceMap: any = new Map([
42+
[ITEM.value, () => import('../../shared/testing/test-data-service.mock').then(m => m.TestDataService)],
43+
]);
4444

4545
describe('DsoEditMetadataComponent', () => {
4646
let component: DsoEditMetadataComponent;

src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
ChangeDetectorRef,
88
Component,
99
Inject,
10-
InjectionToken,
1110
Injector,
1211
Input,
1312
OnDestroy,
@@ -42,7 +41,7 @@ import {
4241
import { ArrayMoveChangeAnalyzer } from '../../core/data/array-move-change-analyzer.service';
4342
import { RemoteData } from '../../core/data/remote-data';
4443
import { UpdateDataService } from '../../core/data/update-data.service';
45-
import { lazyService } from '../../core/lazy-service';
44+
import { lazyDataService } from '../../core/lazy-data-service';
4645
import { DSpaceObject } from '../../core/shared/dspace-object.model';
4746
import { getFirstCompletedRemoteData } from '../../core/shared/operators';
4847
import { ResourceType } from '../../core/shared/resource-type';
@@ -152,7 +151,7 @@ export class DsoEditMetadataComponent implements OnInit, OnDestroy {
152151
protected parentInjector: Injector,
153152
protected arrayMoveChangeAnalyser: ArrayMoveChangeAnalyzer<number>,
154153
protected cdr: ChangeDetectorRef,
155-
@Inject(APP_DATA_SERVICES_MAP) private dataServiceMap: InjectionToken<LazyDataServicesMap>) {
154+
@Inject(APP_DATA_SERVICES_MAP) private dataServiceMap: LazyDataServicesMap) {
156155
}
157156

158157
/**
@@ -186,7 +185,7 @@ export class DsoEditMetadataComponent implements OnInit, OnDestroy {
186185
*/
187186
retrieveDataService(): Observable<UpdateDataService<DSpaceObject>> {
188187
if (hasNoValue(this.updateDataService)) {
189-
const lazyProvider$: Observable<UpdateDataService<DSpaceObject>> = lazyService(this.dataServiceMap[this.dsoType], this.parentInjector);
188+
const lazyProvider$: Observable<UpdateDataService<DSpaceObject>> = lazyDataService(this.dataServiceMap, this.dsoType, this.parentInjector);
190189
return lazyProvider$;
191190
} else {
192191
return EMPTY;

0 commit comments

Comments
 (0)