From d313692da7fddeac7a84c1e798a96e2282d359cd Mon Sep 17 00:00:00 2001 From: Ed Brett Date: Tue, 15 Jan 2019 17:17:36 +0100 Subject: [PATCH] check for undefined state in thunk actions when hmr --- app/javascript/app/router.js | 9 ++++---- .../maps/components/analysis/actions.js | 5 ++-- .../maps/components/menu/menu-actions.js | 13 ++++++----- .../components/maps/main-map/actions.js | 2 +- .../main-map/components/map-tour/actions.js | 4 ++-- .../recent-imagery/recent-imagery-actions.js | 8 ++++--- .../maps/map/components/draw/actions.js | 5 ++-- .../components/modals/subscribe/actions.js | 3 ++- .../components/modals/welcome/actions.js | 4 ++-- app/javascript/components/widgets/actions.js | 3 ++- .../section-impacts-actions.js | 3 ++- .../section-projects-actions.js | 3 ++- app/javascript/pages/dashboards/actions.js | 2 +- .../pages/dashboards/header/header-actions.js | 2 +- .../section-projects-actions.js | 3 ++- .../latest-provider-actions.js | 15 ++++++------ app/javascript/utils/stateToUrl.js | 23 ------------------- 17 files changed, 48 insertions(+), 59 deletions(-) diff --git a/app/javascript/app/router.js b/app/javascript/app/router.js index 27fb05ceed..06832dfffa 100644 --- a/app/javascript/app/router.js +++ b/app/javascript/app/router.js @@ -15,15 +15,16 @@ export const DASHBOARDS = 'location/DASHBOARDS'; export const DASHBOARDS_EMBED = 'location/DASHBOARDS_EMBED'; const routeChangeThunk = (dispatch, getState) => { - const currentLocation = getState().location.pathname; - const prevLocation = getState().location.prev.pathname; + const { location } = getState() || {}; + const currentLocation = location.pathname; + const prevLocation = location.prev.pathname; if (currentLocation !== prevLocation) { - handlePageTrack(getState().location); + handlePageTrack(location); } }; const redirectThunk = (dispatch, getState) => { - const { location } = getState(); + const { location } = getState() || {}; const routeSlugs = location.pathname && location.pathname.split('/'); const isOldMap = routeSlugs.includes('map'); if (isOldMap) { diff --git a/app/javascript/components/maps/components/analysis/actions.js b/app/javascript/components/maps/components/analysis/actions.js index 80d4c91161..3c7b42e968 100644 --- a/app/javascript/components/maps/components/analysis/actions.js +++ b/app/javascript/components/maps/components/analysis/actions.js @@ -165,7 +165,7 @@ export const uploadShape = createThunkAction( export const clearAnalysis = createThunkAction( 'clearAnalysis', () => (dispatch, getState) => { - const { query, type } = getState().location; + const { query, type } = getState().location || {}; dispatch({ type, ...(query && { @@ -179,7 +179,8 @@ export const clearAnalysis = createThunkAction( export const goToDashboard = createThunkAction( 'goToDashboard', () => (dispatch, getState) => { - const { payload, query } = getState().location.query; + const { location } = getState() || {}; + const { payload, query } = location || {}; dispatch({ type: DASHBOARDS, payload, diff --git a/app/javascript/components/maps/components/menu/menu-actions.js b/app/javascript/components/maps/components/menu/menu-actions.js index b1c6d42a31..2f501655f1 100644 --- a/app/javascript/components/maps/components/menu/menu-actions.js +++ b/app/javascript/components/maps/components/menu/menu-actions.js @@ -78,16 +78,17 @@ export const getLocationFromSearch = createThunkAction( export const handleClickLocation = createThunkAction( 'handleClickLocation', ({ gid_0, gid_1, gid_2 }) => (dispatch, getState) => { - const query = getState().location.query || {}; - const location = parseGadm36Id(gid_2 || gid_1 || gid_0); - const { map, menu, mainMap } = getState().location.query || {}; + const { location } = getState(); + const query = (location && location.query) || {}; + const newLocation = parseGadm36Id(gid_2 || gid_1 || gid_0); + const { map, menu, mainMap } = query || {}; - if (location) { + if (newLocation) { dispatch({ type: MAP, payload: { type: 'country', - ...location + ...newLocation }, query: { ...query, @@ -154,7 +155,7 @@ export const handleViewOnMap = createThunkAction( export const showAnalysis = createThunkAction( 'showAnalysis', () => (dispatch, getState) => { - const { query, type, payload } = getState().location; + const { query, type, payload } = getState().location || {}; const { menu } = query || {}; dispatch({ type, diff --git a/app/javascript/components/maps/main-map/actions.js b/app/javascript/components/maps/main-map/actions.js index 89c5f4524d..7be2ff87ac 100644 --- a/app/javascript/components/maps/main-map/actions.js +++ b/app/javascript/components/maps/main-map/actions.js @@ -19,7 +19,7 @@ export const setMainMapAnalysisView = createThunkAction( ({ data, layer }) => (dispatch, getState) => { const { cartodb_id, wdpaid } = data || {}; const { analysisEndpoint, tableName } = layer || {}; - const { query, type } = getState().location; + const { query, type } = getState().location || {}; const { map, mainMap } = query || {}; // get location payload based on layer type diff --git a/app/javascript/components/maps/main-map/components/map-tour/actions.js b/app/javascript/components/maps/main-map/components/map-tour/actions.js index 1229521acd..4b2b3cb4ac 100644 --- a/app/javascript/components/maps/main-map/components/map-tour/actions.js +++ b/app/javascript/components/maps/main-map/components/map-tour/actions.js @@ -5,7 +5,7 @@ export const setMapTourOpen = createAction('setMapTourOpen'); export const setExploreView = createThunkAction( 'setExploreView', () => (dispatch, getState) => { - const { query, type, payload } = getState().location; + const { query, type, payload } = getState().location || {}; dispatch({ type, payload, @@ -22,7 +22,7 @@ export const setExploreView = createThunkAction( export const setAnalysisView = createThunkAction( 'setAnalysisView', () => (dispatch, getState) => { - const { query, type, payload } = getState().location; + const { query, type, payload } = getState().location || {}; dispatch({ type, payload, diff --git a/app/javascript/components/maps/main-map/components/recent-imagery/recent-imagery-actions.js b/app/javascript/components/maps/main-map/components/recent-imagery/recent-imagery-actions.js index 23a6c75ace..5f7b405eca 100644 --- a/app/javascript/components/maps/main-map/components/recent-imagery/recent-imagery-actions.js +++ b/app/javascript/components/maps/main-map/components/recent-imagery/recent-imagery-actions.js @@ -36,7 +36,8 @@ export const setRecentImagerySettings = createThunkAction( export const getRecentImageryData = createThunkAction( 'getRecentImageryData', params => (dispatch, getState) => { - if (!getState().recentImagery.loading) { + const { recentImagery } = getState(); + if (recentImagery && !recentImagery.loading) { dispatch(setRecentImageryLoading(true)); getRecentTiles({ ...params }) .then(response => { @@ -74,7 +75,8 @@ export const getRecentImageryData = createThunkAction( export const getMoreTiles = createThunkAction( 'getMoreTiles', params => (dispatch, getState) => { - if (!getState().recentImagery.loadingMoreTiles) { + const { recentImagery } = getState(); + if (recentImagery && !recentImagery.loadingMoreTiles) { dispatch( setRecentImageryLoadingMoreTiles({ loadingMoreTiles: true, @@ -96,7 +98,7 @@ export const getMoreTiles = createThunkAction( thumbsReponse.data.data.attributes; if (tiles && thumbs) { - const data = getState().recentImagery.data.slice(); + const data = recentImagery && recentImagery.data.slice(); const requestedTiles = dataStatus.requestedTiles + tiles.length; const haveAllData = requestedTiles >= data.length; const newData = data.map((d, i) => { diff --git a/app/javascript/components/maps/map/components/draw/actions.js b/app/javascript/components/maps/map/components/draw/actions.js index c4403dea48..54b147fadd 100644 --- a/app/javascript/components/maps/map/components/draw/actions.js +++ b/app/javascript/components/maps/map/components/draw/actions.js @@ -9,7 +9,8 @@ export const setDrawLoading = createAction('setDrawLoading'); export const getGeostoreId = createThunkAction( 'getGeostoreId', geojson => (dispatch, getState) => { - if (!getState().analysis.loading) { + const { analysis } = getState(); + if (analysis && !analysis.loading) { dispatch(setDrawLoading({ loading: true, error: false, geostoreId: '' })); getGeostoreKey(geojson) .then(geostore => { @@ -33,7 +34,7 @@ export const setDrawnGeostore = createThunkAction( 'setDrawnGeostore', geostoreId => (dispatch, getState) => { track('analysisDrawComplete'); - const { query, type } = getState().location; + const { query, type } = getState().location || {}; const { map } = query || {}; dispatch({ type, diff --git a/app/javascript/components/modals/subscribe/actions.js b/app/javascript/components/modals/subscribe/actions.js index 9f2ec61bd6..cd93a621c2 100644 --- a/app/javascript/components/modals/subscribe/actions.js +++ b/app/javascript/components/modals/subscribe/actions.js @@ -22,7 +22,8 @@ export const setSubscribeSettings = createThunkAction( export const saveSubscription = createThunkAction( 'saveSubscription', data => (dispatch, getState) => { - if (!getState().modalSubscribe.saving) { + const { modalSubscribe } = getState(); + if (modalSubscribe && !modalSubscribe.saving) { dispatch(setSubscribeSaving({ saving: true, error: false })); const { name, diff --git a/app/javascript/components/modals/welcome/actions.js b/app/javascript/components/modals/welcome/actions.js index eeecdb229b..c1a73c7bb1 100644 --- a/app/javascript/components/modals/welcome/actions.js +++ b/app/javascript/components/modals/welcome/actions.js @@ -13,7 +13,7 @@ export const setModalWelcome = createThunkAction( export const setExploreView = createThunkAction( 'setExploreView', () => (dispatch, getState) => { - const { query, type, payload } = getState().location; + const { query, type, payload } = getState().location || {}; dispatch(setModalWelcome(false)); dispatch({ type, @@ -31,7 +31,7 @@ export const setExploreView = createThunkAction( export const setAnalysisView = createThunkAction( 'setAnalysisView', () => (dispatch, getState) => { - const { query, type, payload } = getState().location; + const { query, type, payload } = getState().location || {}; dispatch(setModalWelcome(false)); dispatch({ type, diff --git a/app/javascript/components/widgets/actions.js b/app/javascript/components/widgets/actions.js index fbafb4a078..98b5e4be0d 100644 --- a/app/javascript/components/widgets/actions.js +++ b/app/javascript/components/widgets/actions.js @@ -17,7 +17,8 @@ export const setWidgetLoading = createAction('setWidgetLoading'); export const getWidgetsData = createThunkAction( 'getWidgetsData', () => (dispatch, getState) => { - if (!getState().widgets.loading) { + const { widgets } = getState(); + if (widgets && !widgets.loading) { dispatch(setWidgetsLoading({ loading: true, error: false })); getNonGlobalDatasets() .then(response => { diff --git a/app/javascript/pages/about/section-impacts/section-impacts-actions.js b/app/javascript/pages/about/section-impacts/section-impacts-actions.js index 3dd7e2ab2c..af54dec9a5 100644 --- a/app/javascript/pages/about/section-impacts/section-impacts-actions.js +++ b/app/javascript/pages/about/section-impacts/section-impacts-actions.js @@ -10,7 +10,8 @@ export const setImpactsProjectsData = createAction('setImpactsProjectsData'); export const fetchImpactProjects = createThunkAction( 'fetchImpactProjects', () => (dispatch, getState) => { - if (!getState().impacts.loading) { + const { impacts } = getState(); + if (impacts && !impacts.loading) { dispatch(setImpactsProjectsLoading({ loading: true, error: false })); fetchAboutProjects() .then(data => { diff --git a/app/javascript/pages/about/section-projects/section-projects-actions.js b/app/javascript/pages/about/section-projects/section-projects-actions.js index 93846c0023..53f02308fc 100644 --- a/app/javascript/pages/about/section-projects/section-projects-actions.js +++ b/app/javascript/pages/about/section-projects/section-projects-actions.js @@ -9,7 +9,8 @@ export const setCategorySelected = createAction('setCategorySelected'); export const fetchProjects = createThunkAction( 'fetchProjects', () => (dispatch, getState) => { - if (!getState().aboutProjects.loading) { + const { aboutProjects } = getState(); + if (aboutProjects && !aboutProjects.loading) { dispatch(setProjectsLoading({ loading: true, error: false })); fetchAllProjects() .then(data => { diff --git a/app/javascript/pages/dashboards/actions.js b/app/javascript/pages/dashboards/actions.js index 055ad7c274..514c892256 100644 --- a/app/javascript/pages/dashboards/actions.js +++ b/app/javascript/pages/dashboards/actions.js @@ -3,7 +3,7 @@ import { createThunkAction } from 'redux-tools'; export const handleCategoryChange = createThunkAction( 'handleCategoryChange', category => (dispatch, getState) => { - const { query, type, payload } = getState().location; + const { query, type, payload } = getState().location || {}; dispatch({ type, payload, diff --git a/app/javascript/pages/dashboards/header/header-actions.js b/app/javascript/pages/dashboards/header/header-actions.js index eb49c340c4..33652e13c9 100644 --- a/app/javascript/pages/dashboards/header/header-actions.js +++ b/app/javascript/pages/dashboards/header/header-actions.js @@ -105,7 +105,7 @@ export const getHeaderData = createThunkAction( export const handleLocationChange = createThunkAction( 'handleLocationChange', location => (dispatch, getState) => { - const { query, type } = getState().location; + const { query, type } = getState().location || {}; const newQuery = {}; if (query) { diff --git a/app/javascript/pages/sgf/section-projects/section-projects-actions.js b/app/javascript/pages/sgf/section-projects/section-projects-actions.js index 84f0ed20b1..d18bd570e8 100644 --- a/app/javascript/pages/sgf/section-projects/section-projects-actions.js +++ b/app/javascript/pages/sgf/section-projects/section-projects-actions.js @@ -15,7 +15,8 @@ export const setSearch = createAction('setSearch'); export const fetchProjects = createThunkAction( 'fetchProjects', () => (dispatch, getState) => { - if (!getState().sgfProjects.loading) { + const { sgfProjects } = getState(); + if (sgfProjects && !sgfProjects.loading) { dispatch(setProjectsLoading({ loading: true, error: false })); axios .all([fetchSGFProjects(), getCountriesProvider(), getCountriesLatLng()]) diff --git a/app/javascript/providers/latest-provider/latest-provider-actions.js b/app/javascript/providers/latest-provider/latest-provider-actions.js index 80041ebfbd..f58959fa17 100644 --- a/app/javascript/providers/latest-provider/latest-provider-actions.js +++ b/app/javascript/providers/latest-provider/latest-provider-actions.js @@ -10,7 +10,8 @@ export const setLatestDates = createAction('setLatestDates'); export const getLatest = createThunkAction( 'getLatest', latestEndpoints => (dispatch, getState) => { - const currentLatestDates = Object.keys(getState().latest.data); + const { latest } = getState(); + const currentLatestDates = latest && Object.keys(latest.data); const newEndpoints = latestEndpoints.filter( l => !currentLatestDates.includes(l.id) ); @@ -23,13 +24,13 @@ export const getLatest = createThunkAction( const latestDates = responses && responses.reduce((obj, response, index) => { - const latest = response.data.data || response.data; - let date = latest.date; + const latestResponse = response.data.data || response.data; + let date = latestResponse.date; if (!date) { - const data = Array.isArray(latest) - ? latest[0].attributes - : latest.attributes; - date = data.date || data.latest; + const data = Array.isArray(latestResponse) + ? latestResponse[0].attributes + : latestResponse.attributes; + date = data.date || data.latestResponse; } return { ...obj, diff --git a/app/javascript/utils/stateToUrl.js b/app/javascript/utils/stateToUrl.js index 767df2b8e1..58f4d759bc 100644 --- a/app/javascript/utils/stateToUrl.js +++ b/app/javascript/utils/stateToUrl.js @@ -1,5 +1,3 @@ -// import isEqual from 'lodash/isEqual'; -// import pick from 'lodash/pick'; import queryString from 'query-string'; export const decodeUrlForState = url => { @@ -47,24 +45,3 @@ export const setComponentStateToUrl = ({ key, subKey, change, state }) => { } }; }; - -// export const isObjectContained = (contained, container) => -// isEqual(pick(container, Object.keys(contained)), contained); - -// export const setUrlStateToStore = ({ -// key, -// query, -// setState, -// dispatch, -// getState -// }) => { -// if (query && query[key]) { -// const state = decodeUrlForState(query[key]); -// const { settings } = getState()[key]; -// // Check if the state needs and update checking the values of the new config -// // with the existing in the url to avoid dispatch actions without changes -// if (!isObjectContained(state, settings)) { -// dispatch(setState(state)); -// } -// } -// };