diff --git a/src/app/+collection-page/collection-page.component.html b/src/app/+collection-page/collection-page.component.html index 0be1787854..f66095b004 100644 --- a/src/app/+collection-page/collection-page.component.html +++ b/src/app/+collection-page/collection-page.component.html @@ -36,16 +36,16 @@
-
+

{{'collection.page.browse.recent.head' | translate}}

- - + +
diff --git a/src/app/+collection-page/collection-page.component.ts b/src/app/+collection-page/collection-page.component.ts index 2ca547dada..cec4e8b497 100644 --- a/src/app/+collection-page/collection-page.component.ts +++ b/src/app/+collection-page/collection-page.component.ts @@ -30,7 +30,7 @@ import { PaginationComponentOptions } from '../shared/pagination/pagination-comp }) export class CollectionPageComponent implements OnInit, OnDestroy { collectionData: Observable>; - itemData: RemoteData; + itemData: Observable>; logoData: Observable>; 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) => { - this.itemData = rd; - })); + }); } ngOnDestroy(): void { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 435b44b933..41baedc842 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -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); - } - - } diff --git a/src/app/core/data/remote-data.ts b/src/app/core/data/remote-data.ts index a832759632..d8a2f79e66 100644 --- a/src/app/core/data/remote-data.ts +++ b/src/app/core/data/remote-data.ts @@ -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 { } 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 } } diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts index 6109e7b45c..3036c7be21 100644 --- a/src/app/core/data/request.service.ts +++ b/src/app/core/data/request.service.ts @@ -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 { return keySelector('data/request', href); } +export function requestStateSelector(): MemoizedSelector { + 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(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) diff --git a/src/app/core/shared/hal-endpoint.service.ts b/src/app/core/shared/hal-endpoint.service.ts index 61f528d714..fa11fed308 100644 --- a/src/app/core/shared/hal-endpoint.service.ts +++ b/src/app/core/shared/hal-endpoint.service.ts @@ -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) diff --git a/src/modules/app/server-app.module.ts b/src/modules/app/server-app.module.ts index d97c13a7bb..eaac592dff 100644 --- a/src/modules/app/server-app.module.ts +++ b/src/modules/app/server-app.module.ts @@ -36,8 +36,16 @@ export function boot(cache: TransferState, appRef: ApplicationRef, store: Store< // authentication mechanism goes here return () => { appRef.isStable.filter((stable: boolean) => stable).first().subscribe(() => { - cache.inject(); - }); + // 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); + }); }; }