From da589f62f7c2c026d8e50e047cd47b39aa810025 Mon Sep 17 00:00:00 2001 From: qlj-lijuan <43854757+qlj-lijuan@users.noreply.github.com> Date: Fri, 7 Aug 2020 17:11:52 -0400 Subject: [PATCH] handle hash change to support re-render when the link on home page is clicked (#262) * handle on hash change * move listenHashChange to timelineParams --- static/js/tools/statsvar_menu.tsx | 2 +- static/js/tools/timeline_page.test.tsx | 2 +- static/js/tools/timeline_page.tsx | 31 +++++++++++++++++++++++--- static/js/tools/timeline_util.ts | 11 ++++++++- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/static/js/tools/statsvar_menu.tsx b/static/js/tools/statsvar_menu.tsx index e8b529ef3c..6e5a83067e 100644 --- a/static/js/tools/statsvar_menu.tsx +++ b/static/js/tools/statsvar_menu.tsx @@ -131,7 +131,7 @@ class Node extends Component { } private onUpdate() { - let check = this.state.checked; + let check = false; let expand = this.state.expanded; for (const statsVar in this.props.selectedNodes) { for (const nodePath of this.props.selectedNodes[statsVar]) { diff --git a/static/js/tools/timeline_page.test.tsx b/static/js/tools/timeline_page.test.tsx index f93a804dc2..7e9e08c6b2 100644 --- a/static/js/tools/timeline_page.test.tsx +++ b/static/js/tools/timeline_page.test.tsx @@ -35,7 +35,7 @@ test("Single place and single stats var", () => { // Set url hash Object.defineProperty(window, "location", { value: { - hash: "&place=geoId/05&statsVar=Median_Age_Person", + hash: "#&place=geoId/05&statsVar=Median_Age_Person", }, }); // Mock drawGroupLineChart() as getComputedTextLength can has issue with jest diff --git a/static/js/tools/timeline_page.tsx b/static/js/tools/timeline_page.tsx index ce3d39ff69..47d5592b20 100644 --- a/static/js/tools/timeline_page.tsx +++ b/static/js/tools/timeline_page.tsx @@ -48,6 +48,7 @@ class Page extends Component, PageStateType> { constructor(props: Record) { super(props); + this.handleHashChange = this.handleHashChange.bind(this); this.params = new TimelineParams(); this.params.getParamsFromUrl(); // set default statsVarTitle as the statsVar dcids @@ -66,8 +67,33 @@ class Page extends Component, PageStateType> { } componentDidMount(): void { - // Initial rendering has emmpty state. This proactively parse the url hash - // and re-render. + window.addEventListener("hashchange", this.handleHashChange); + this.getAllPromises(); + } + + private handleHashChange(): void { + if (this.params.listenHashChange) { + // do not update if it's set by calling add/remove place/statsVar + this.params.getParamsFromUrl(); + if ( + !_.isEqual(this.params.statsVarNodes, this.state.statsVarNodes) || + !_.isEqual( + this.params.placeDcids, + Object.keys(this.state.placeIdNames) + ) || + this.params.pc !== this.state.perCapita + ) { + this.setState({ + statsVarNodes: _.cloneDeep(this.params.statsVarNodes), + perCapita: this.params.pc, + }); + this.getAllPromises(); + } + } + this.params.listenHashChange = true; + } + + private getAllPromises(): void { let statsVarInfoPromise = Promise.resolve({}); if (this.params.getStatsVarDcids().length !== 0) { statsVarInfoPromise = getStatsVarInfo(this.params.getStatsVarDcids()); @@ -78,7 +104,6 @@ class Page extends Component, PageStateType> { placesPromise = getPlaceNames(this.params.placeDcids); validStatsVarPromise = getStatsVar(this.params.placeDcids); } - Promise.all([ statsVarInfoPromise, placesPromise, diff --git a/static/js/tools/timeline_util.ts b/static/js/tools/timeline_util.ts index cd8b93bb1f..6b4021f353 100644 --- a/static/js/tools/timeline_util.ts +++ b/static/js/tools/timeline_util.ts @@ -290,6 +290,7 @@ class TimelineParams { placeDcids: string[]; pc: boolean; urlParams: URLSearchParams; + listenHashChange: boolean; constructor() { this.statsVarNodes = {}; @@ -300,6 +301,7 @@ class TimelineParams { this.addPlace = this.addPlace.bind(this); this.removePLace = this.removePLace.bind(this); this.urlParams = new URLSearchParams(""); + this.listenHashChange = true; } // set PerCapital to true @@ -375,12 +377,14 @@ class TimelineParams { // set PerCapita in url public setUrlPerCapita(): void { this.urlParams.set("pc", this.pc ? "1" : "0"); + this.listenHashChange = false; window.location.hash = this.urlParams.toString(); } // set places in url public setUrlPlaces(): void { this.urlParams.set("place", this.placeDcids.join(placeSep)); + this.listenHashChange = false; window.location.hash = this.urlParams.toString(); } @@ -393,6 +397,7 @@ class TimelineParams { ); } this.urlParams.set("statsVar", statsVarArray.join(statsVarSep)); + this.listenHashChange = false; window.location.hash = this.urlParams.toString(); } @@ -414,7 +419,11 @@ class TimelineParams { // get the timeline parameters from the url public getParamsFromUrl(): void { - this.urlParams = new URLSearchParams(window.location.hash); + // get the url, remove the leading hash symbol "#" + this.urlParams = new URLSearchParams(window.location.hash.split("#")[1]); + this.statsVarNodes = {}; + this.placeDcids = []; + this.pc = false; // set Per Capita const pc = this.urlParams.get("pc"); if (pc === "1") {