mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-16 22:43:03 +00:00
fixed an issue where a rehydrate would sometimes leave the app in a broken state
This commit is contained in:
@@ -36,16 +36,16 @@
|
||||
<ds-error *ngIf="(collectionData | async)?.hasFailed" message="{{'error.collection' | translate}}"></ds-error>
|
||||
<ds-loading *ngIf="(collectionData | async)?.isLoading" message="{{'loading.collection' | translate}}"></ds-loading>
|
||||
<br>
|
||||
<div *ngIf="itemData?.hasSucceeded" @fadeIn>
|
||||
<div *ngIf="(itemData | async)?.hasSucceeded" @fadeIn>
|
||||
<h2>{{'collection.page.browse.recent.head' | translate}}</h2>
|
||||
<ds-object-list
|
||||
[config]="paginationConfig"
|
||||
[sortConfig]="sortConfig"
|
||||
[objects]="itemData"
|
||||
[objects]="(itemData | async)"
|
||||
[hideGear]="false"
|
||||
(paginationChange)="onPaginationChange($event)">
|
||||
</ds-object-list>
|
||||
</div>
|
||||
<ds-error *ngIf="itemData?.hasFailed" message="{{'error.recent-submissions' | translate}}"></ds-error>
|
||||
<ds-loading *ngIf="!itemData || itemData.isLoading" message="{{'loading.recent-submissions' | translate}}"></ds-loading>
|
||||
<ds-error *ngIf="(itemData | async)?.hasFailed" message="{{'error.recent-submissions' | translate}}"></ds-error>
|
||||
<ds-loading *ngIf="!(itemData | async) || (itemData | async).isLoading" message="{{'loading.recent-submissions' | translate}}"></ds-loading>
|
||||
</div>
|
||||
|
@@ -30,7 +30,7 @@ import { PaginationComponentOptions } from '../shared/pagination/pagination-comp
|
||||
})
|
||||
export class CollectionPageComponent implements OnInit, OnDestroy {
|
||||
collectionData: Observable<RemoteData<Collection>>;
|
||||
itemData: RemoteData<Item[]>;
|
||||
itemData: Observable<RemoteData<Item[]>>;
|
||||
logoData: Observable<RemoteData<Bitstream>>;
|
||||
paginationConfig: PaginationComponentOptions;
|
||||
sortConfig: SortOptions;
|
||||
@@ -87,14 +87,12 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
updatePage(searchOptions) {
|
||||
this.subs.push(this.itemDataService.findAll({
|
||||
this.itemData = this.itemDataService.findAll({
|
||||
scopeID: this.collectionId,
|
||||
currentPage: searchOptions.pagination.currentPage,
|
||||
elementsPerPage: searchOptions.pagination.pageSize,
|
||||
sort: searchOptions.sort
|
||||
}).subscribe((rd: RemoteData<Item[]>) => {
|
||||
this.itemData = rd;
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
|
@@ -1,32 +1,32 @@
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
HostListener,
|
||||
Inject,
|
||||
ViewEncapsulation,
|
||||
OnInit,
|
||||
HostListener, SimpleChanges, OnChanges
|
||||
ViewEncapsulation
|
||||
} from '@angular/core';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { TransferState } from '../modules/transfer-state/transfer-state';
|
||||
import { HostWindowState } from './shared/host-window.reducer';
|
||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||
import { NativeWindowRef, NativeWindowService } from './shared/window.service';
|
||||
import { MetadataService } from './core/metadata/metadata.service';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../config';
|
||||
|
||||
import { TransferState } from '../modules/transfer-state/transfer-state';
|
||||
import { MetadataService } from './core/metadata/metadata.service';
|
||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||
import { HostWindowState } from './shared/host-window.reducer';
|
||||
import { NativeWindowRef, NativeWindowService } from './shared/window.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-app',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.Default,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class AppComponent implements OnInit, OnChanges {
|
||||
export class AppComponent implements OnInit {
|
||||
|
||||
constructor(
|
||||
@Inject(GLOBAL_CONFIG) public config: GlobalConfig,
|
||||
@@ -71,9 +71,4 @@ export class AppComponent implements OnInit, OnChanges {
|
||||
);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
console.log('AppComponent: onchanges called', changes);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { PageInfo } from '../shared/page-info.model';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
|
||||
export enum RemoteDataState {
|
||||
RequestPending = 'RequestPending',
|
||||
@@ -26,13 +25,13 @@ export class RemoteData<T> {
|
||||
}
|
||||
|
||||
get state(): RemoteDataState {
|
||||
if (this.isSuccessFul === true) {
|
||||
if (this.isSuccessFul === true && hasValue(this.payload)) {
|
||||
return RemoteDataState.Success
|
||||
} else if (this.isSuccessFul === false) {
|
||||
return RemoteDataState.Failed
|
||||
} else if (this.requestPending === true) {
|
||||
return RemoteDataState.RequestPending
|
||||
} else if (this.responsePending === true || this.isSuccessFul === undefined) {
|
||||
} else {
|
||||
return RemoteDataState.ResponsePending
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { MemoizedSelector, Store } from '@ngrx/store';
|
||||
import { createSelector, MemoizedSelector, Store } from '@ngrx/store';
|
||||
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
@@ -9,17 +9,24 @@ import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { DSOSuccessResponse, RestResponse } from '../cache/response-cache.models';
|
||||
import { ResponseCacheEntry } from '../cache/response-cache.reducer';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
import { CoreState } from '../core.reducers';
|
||||
import { coreSelector, CoreState } from '../core.reducers';
|
||||
import { keySelector } from '../shared/selectors';
|
||||
import { RequestConfigureAction, RequestExecuteAction } from './request.actions';
|
||||
import { RestRequest } from './request.models';
|
||||
|
||||
import { RequestEntry } from './request.reducer';
|
||||
import { RequestEntry, RequestState } from './request.reducer';
|
||||
|
||||
function entryFromHrefSelector(href: string): MemoizedSelector<CoreState, RequestEntry> {
|
||||
return keySelector<RequestEntry>('data/request', href);
|
||||
}
|
||||
|
||||
export function requestStateSelector(): MemoizedSelector<CoreState, RequestState> {
|
||||
return createSelector(coreSelector, (state: CoreState) => {
|
||||
return state['data/request'] as RequestState;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class RequestService {
|
||||
private requestsOnTheirWayToTheStore: string[] = [];
|
||||
@@ -54,7 +61,6 @@ export class RequestService {
|
||||
|
||||
configure<T extends CacheableObject>(request: RestRequest): void {
|
||||
let isCached = this.objectCache.hasBySelfLink(request.href);
|
||||
// console.log('request.href', request.href);
|
||||
if (!isCached && this.responseCache.has(request.href)) {
|
||||
const [successResponse, errorResponse] = this.responseCache.get(request.href)
|
||||
.take(1)
|
||||
|
@@ -17,7 +17,6 @@ export abstract class HALEndpointService {
|
||||
const request = new RootEndpointRequest(this.EnvConfig);
|
||||
this.requestService.configure(request);
|
||||
return this.responseCache.get(request.href)
|
||||
// .do((entry: ResponseCacheEntry) => console.log('entry.response', entry.response))
|
||||
.map((entry: ResponseCacheEntry) => entry.response)
|
||||
.filter((response: RootSuccessResponse) => isNotEmpty(response) && isNotEmpty(response.endpointMap))
|
||||
.map((response: RootSuccessResponse) => response.endpointMap)
|
||||
|
@@ -36,7 +36,15 @@ export function boot(cache: TransferState, appRef: ApplicationRef, store: Store<
|
||||
// authentication mechanism goes here
|
||||
return () => {
|
||||
appRef.isStable.filter((stable: boolean) => stable).first().subscribe(() => {
|
||||
// isStable == true doesn't guarantee that all dispatched actions have been
|
||||
// processed yet. So in those cases the store snapshot wouldn't be complete
|
||||
// and a rehydrate would leave the app in a broken state
|
||||
//
|
||||
// This setTimeout without delay schedules the cache.inject() to happen ASAP
|
||||
// after everything that's already scheduled, and it solves that problem.
|
||||
setTimeout(() => {
|
||||
cache.inject();
|
||||
}, 0);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user