From c215734cb06830afb7a37214502e489572d68df5 Mon Sep 17 00:00:00 2001 From: Bart Langelaan Date: Thu, 7 Feb 2019 21:32:06 +0100 Subject: [PATCH] fix(hn): don't return uuid if it isn't fully loaded yet --- .../hn-react/src/components/DrupalPage.tsx | 2 +- packages/hn/src/Site.ts | 105 +++++++++++------- 2 files changed, 63 insertions(+), 44 deletions(-) diff --git a/packages/hn-react/src/components/DrupalPage.tsx b/packages/hn-react/src/components/DrupalPage.tsx index 16cf3413..f73b5e8e 100644 --- a/packages/hn-react/src/components/DrupalPage.tsx +++ b/packages/hn-react/src/components/DrupalPage.tsx @@ -167,7 +167,7 @@ class DrupalPage extends React.Component< return null; } - const uuid = this.props.site.getUuid(data.url); + const uuid = this.props.site.getUuid(data.url)!; const entityMapper = ( } = {}; + private pagesLoaded: { [s: string]: string } = {}; constructor(initParams?: SiteInitializeParams) { this.reset(); @@ -49,6 +50,7 @@ class Site { __hn: {}, }; this.pagesLoading = {}; + this.pagesLoaded = {}; } /** @@ -97,58 +99,75 @@ class Site { } public getPage(path, loadFromServer = false): Promise { - if (!this.pagesLoading[path]) { - const dataMaybeAlreadyLoaded = getNested( - () => this.data.data[this.data.paths[path]], - ); - if ( - getNested(() => - dataMaybeAlreadyLoaded.__hn.view_modes.includes('default'), - ) - ) { - this.pagesLoading[path] = Promise.resolve(this.data.paths[path]); - } + if (!loadFromServer) { + const uuid = this.getUuid(path); + + // If we already loaded the page (either directly or via another page), + // we can return it right now. + if (uuid) return Promise.resolve(uuid); + + // If we're already loading this page, we should return the promise. + if (this.pagesLoading[path]) return this.pagesLoading[path]; } - if (loadFromServer || !this.pagesLoading[path]) { - // Copy this.tokensToVerify for this single request. - const tokensToVerify = [...this.tokensToVerify]; - - this.pagesLoading[path] = this.fetch( - '/hn?' + - stringify({ - path, - _format: 'hn', - _hn_user: this.user ? this.user : undefined, - _hn_verify: tokensToVerify, - }), - ).then((page: HnServerResponse) => { - const hnRequestData = - (page.__hn && page.__hn.request && page.__hn.request) || {}; - - // Get the user id, to pass to all new requests. - this.user = hnRequestData.user || this.user; - - // Remove all sent tokens from the tokensToVerify. - this.tokensToVerify = this.tokensToVerify.filter( - t => tokensToVerify.indexOf(t) === -1, - ); + // Copy this.tokensToVerify for this single request. + const tokensToVerify = [...this.tokensToVerify]; + + this.pagesLoading[path] = this.fetch( + '/hn?' + + stringify({ + path, + _format: 'hn', + _hn_user: this.user ? this.user : undefined, + _hn_verify: tokensToVerify, + }), + ).then((page: HnServerResponse) => { + const hnRequestData = + (page.__hn && page.__hn.request && page.__hn.request) || {}; + + // Get the user id, to pass to all new requests. + this.user = hnRequestData.user || this.user; + + // Remove all sent tokens from the tokensToVerify. + this.tokensToVerify = this.tokensToVerify.filter( + t => tokensToVerify.indexOf(t) === -1, + ); - // Add new token to tokensToVerify. - const newToken = hnRequestData.token; - if (newToken) this.tokensToVerify.push(newToken); + // Add new token to tokensToVerify. + const newToken = hnRequestData.token; + if (newToken) this.tokensToVerify.push(newToken); - // Add all data to the global data storage. - this.addData(page); + // Add all data to the global data storage. + this.addData(page); + + // Mark this promise as loaded + const uuid = this.data.paths[path]; + this.pagesLoaded[path] = uuid; + + // Delete the reference to this promise, because we're not loading anymore. + delete this.pagesLoading[path]; + + return uuid; + }); - return this.data.paths[path]; - }); - } return this.pagesLoading[path]; } public getUuid(path: string) { - return this.data.paths[path]; + // If we already loaded the page, we can return it right now. + if (this.pagesLoaded[path]) return this.pagesLoaded[path]; + + // Maybe we already have the data from another fetch. + try { + // We try to get the data directly. If the data isn't available, that's fine. + const uuid = this.data.paths[path]; + if (this.getData(uuid).__hn.view_modes.includes('default')) { + return uuid; + } + } + catch { + // The data probabily doesn't exist yet, so we do nothing. + } } private addData(data: HnServerResponse) {