From a54ebc8710c712b0f9d93107c916331ebb52ce3b Mon Sep 17 00:00:00 2001 From: jlpereira Date: Sun, 20 Aug 2023 00:06:25 -0300 Subject: [PATCH 1/2] Cancel previous request. Fix #123 --- .../Panel/PanelContent/PanelContent.vue | 36 +++---- .../Panel/PanelDescendants/Descendants.vue | 4 +- .../PanelDescendants/DescendantsTree.vue | 4 +- .../components/Panel/PanelGallery/Gallery.vue | 11 ++- .../components/Panel/PanelMap/PanelMap.vue | 11 ++- src/modules/otus/constants/index.js | 3 +- src/modules/otus/constants/overviewLayout.js | 2 +- src/modules/otus/constants/responseError.js | 3 + src/modules/otus/helpers/useOtuPageRequest.js | 5 +- src/modules/otus/services/TaxonWorks.js | 38 ++++---- src/modules/otus/store/actions/index.js | 1 - src/modules/otus/store/actions/loadCatalog.js | 4 +- .../otus/store/actions/loadDistribution.js | 56 ----------- .../otus/store/actions/loadTaxonomy.js | 9 +- src/modules/otus/store/store.js | 49 +++------- .../otus/store/useDistributionStore.js | 96 +++++++++++++++++++ src/modules/otus/store/useImageStore.js | 44 +++++++++ src/modules/otus/views/Index.vue | 20 ++-- 18 files changed, 245 insertions(+), 151 deletions(-) create mode 100644 src/modules/otus/constants/responseError.js delete mode 100644 src/modules/otus/store/actions/loadDistribution.js create mode 100644 src/modules/otus/store/useDistributionStore.js create mode 100644 src/modules/otus/store/useImageStore.js diff --git a/src/modules/otus/components/Panel/PanelContent/PanelContent.vue b/src/modules/otus/components/Panel/PanelContent/PanelContent.vue index d59489a..e2938b4 100644 --- a/src/modules/otus/components/Panel/PanelContent/PanelContent.vue +++ b/src/modules/otus/components/Panel/PanelContent/PanelContent.vue @@ -10,7 +10,7 @@ diff --git a/src/modules/otus/components/Panel/PanelDescendants/Descendants.vue b/src/modules/otus/components/Panel/PanelDescendants/Descendants.vue index 32cb99d..f7c8822 100644 --- a/src/modules/otus/components/Panel/PanelDescendants/Descendants.vue +++ b/src/modules/otus/components/Panel/PanelDescendants/Descendants.vue @@ -54,7 +54,9 @@ watch( isLoading.value = true useOtuPageRequest('panel:descendants', () => - TaxonWorks.getTaxonomy(props.otuId, { max_descendants_depth: 1 }) + TaxonWorks.getTaxonomy(props.otuId, { + params: { max_descendants_depth: 1 } + }) ) .then(({ data }) => { taxonomy.value = data diff --git a/src/modules/otus/components/Panel/PanelDescendants/DescendantsTree.vue b/src/modules/otus/components/Panel/PanelDescendants/DescendantsTree.vue index d316de5..c85e6aa 100644 --- a/src/modules/otus/components/Panel/PanelDescendants/DescendantsTree.vue +++ b/src/modules/otus/components/Panel/PanelDescendants/DescendantsTree.vue @@ -71,7 +71,9 @@ const loadDescendants = () => { return } TaxonWorks.getTaxonomy(props.taxonomy.otu_id, { - max_descendants_depth: 1 + params: { + max_descendants_depth: 1 + } }).then(({ data }) => { descendants.value = data.descendants }) diff --git a/src/modules/otus/components/Panel/PanelGallery/Gallery.vue b/src/modules/otus/components/Panel/PanelGallery/Gallery.vue index ac2d77c..ec4196c 100644 --- a/src/modules/otus/components/Panel/PanelGallery/Gallery.vue +++ b/src/modules/otus/components/Panel/PanelGallery/Gallery.vue @@ -7,8 +7,8 @@ diff --git a/src/modules/otus/components/Panel/PanelMap/PanelMap.vue b/src/modules/otus/components/Panel/PanelMap/PanelMap.vue index 9218bb6..5627a13 100644 --- a/src/modules/otus/components/Panel/PanelMap/PanelMap.vue +++ b/src/modules/otus/components/Panel/PanelMap/PanelMap.vue @@ -58,8 +58,8 @@ diff --git a/src/modules/otus/constants/index.js b/src/modules/otus/constants/index.js index b7becd8..2686a8f 100644 --- a/src/modules/otus/constants/index.js +++ b/src/modules/otus/constants/index.js @@ -1,2 +1,3 @@ -export * from './typeOrder' export * from './rankGroups' +export * from './responseError' +export * from './typeOrder' diff --git a/src/modules/otus/constants/overviewLayout.js b/src/modules/otus/constants/overviewLayout.js index 31cc0d9..052d7b6 100644 --- a/src/modules/otus/constants/overviewLayout.js +++ b/src/modules/otus/constants/overviewLayout.js @@ -1,4 +1,4 @@ -import { FAMILY_GROUP, GENUS_GROUP, SPECIES_GROUP } from './index.js' +import { FAMILY_GROUP, GENUS_GROUP, SPECIES_GROUP } from './rankGroups.js' import PanelGallery from '../components/Panel/PanelGallery/Gallery.vue' import PanelTypeSpecimen from '../components/Panel/PanelTypeSpecimen/PanelTypeSpecimen.vue' import PanelTypeDesignation from '../components/Panel/PanelTypeDesignation/PanelTypeDesignation.vue' diff --git a/src/modules/otus/constants/responseError.js b/src/modules/otus/constants/responseError.js new file mode 100644 index 0000000..258d560 --- /dev/null +++ b/src/modules/otus/constants/responseError.js @@ -0,0 +1,3 @@ +export const RESPONSE_ERROR = { + CanceledError: 'CanceledError' +} diff --git a/src/modules/otus/helpers/useOtuPageRequest.js b/src/modules/otus/helpers/useOtuPageRequest.js index 3c72698..5b86aaa 100644 --- a/src/modules/otus/helpers/useOtuPageRequest.js +++ b/src/modules/otus/helpers/useOtuPageRequest.js @@ -1,4 +1,5 @@ import { useOtuPageRequestStore } from '../store/request' +import { RESPONSE_ERROR } from '../constants' export function useOtuPageRequest(key, requestFunction) { const store = useOtuPageRequestStore() @@ -9,7 +10,9 @@ export function useOtuPageRequest(key, requestFunction) { store.setRequest(key, response) }) .catch((error) => { - store.setRequest(key, error.response) + if (error.name !== RESPONSE_ERROR.CanceledError) { + store.setRequest(key, error.response) + } }) return request diff --git a/src/modules/otus/services/TaxonWorks.js b/src/modules/otus/services/TaxonWorks.js index 55cb24a..05a4f5a 100644 --- a/src/modules/otus/services/TaxonWorks.js +++ b/src/modules/otus/services/TaxonWorks.js @@ -1,8 +1,8 @@ import { makeAPIRequest } from '@/utils/request' export default class TaxonWorks { - static getTaxonNameCitations(taxonId) { - return makeAPIRequest.get(`/taxon_names/${taxonId}/inventory/catalog`) + static getTaxonNameCitations(taxonId, opt) { + return makeAPIRequest.get(`/taxon_names/${taxonId}/inventory/catalog`, opt) } static getOtu(id) { @@ -17,12 +17,12 @@ export default class TaxonWorks { }) } - static getTaxon(id) { - return makeAPIRequest.get(`/taxon_names/${id}`) + static getTaxon(id, opt) { + return makeAPIRequest.get(`/taxon_names/${id}`, opt) } - static summary(id) { - return makeAPIRequest.get(`/taxon_names/${id}/inventory/summary`) + static summary(id, opt) { + return makeAPIRequest.get(`/taxon_names/${id}/inventory/summary`, opt) } static getTaxonTypeDesignation(id) { @@ -31,38 +31,32 @@ export default class TaxonWorks { }) } - static getOtuImages(otuId, params = {}) { - return makeAPIRequest.get(`/otus/${otuId}/inventory/images.json`, { - params - }) + static getOtuImages(otuId, opt) { + return makeAPIRequest.get(`/otus/${otuId}/inventory/images.json`, opt) } - static getTaxonomy(otuId, params) { - return makeAPIRequest.get(`/otus/${otuId}/inventory/taxonomy.json`, { - params - }) + static getTaxonomy(otuId, opt) { + return makeAPIRequest.get(`/otus/${otuId}/inventory/taxonomy.json`, opt) } static getOtuTypeMaterial(otuId) { return makeAPIRequest.get(`/otus/${otuId}/inventory/type_material.json`) } - static getOtuDistribution(otuId) { - return makeAPIRequest.get(`/otus/${otuId}/inventory/distribution.json`) + static getOtuDistribution(otuId, opt = {}) { + return makeAPIRequest.get(`/otus/${otuId}/inventory/distribution.json`, opt) } static getOtuGeoJSONDistribution(otuId) { return makeAPIRequest.get(`/otus/${otuId}/inventory/distribution.geojson`) } - static getCachedMap(cachedId) { - return makeAPIRequest.get(`/cached_maps/${cachedId}`) + static getCachedMap(cachedId, opt) { + return makeAPIRequest.get(`/cached_maps/${cachedId}`, opt) } - static getOtuContent(otuId) { - return makeAPIRequest.get(`/otus/${otuId}/inventory/content`, { - extend: ['depiction'] - }) + static getOtuContent(otuId, opt) { + return makeAPIRequest.get(`/otus/${otuId}/inventory/content`, opt) } static getCachedMap(id) { diff --git a/src/modules/otus/store/actions/index.js b/src/modules/otus/store/actions/index.js index 9f27990..ef6d079 100644 --- a/src/modules/otus/store/actions/index.js +++ b/src/modules/otus/store/actions/index.js @@ -1,4 +1,3 @@ export * from './loadCatalog' -export * from './loadDistribution' export * from './loadTaxonomy' export * from './loadCachedMap' diff --git a/src/modules/otus/store/actions/loadCatalog.js b/src/modules/otus/store/actions/loadCatalog.js index b36a563..005c760 100644 --- a/src/modules/otus/store/actions/loadCatalog.js +++ b/src/modules/otus/store/actions/loadCatalog.js @@ -2,11 +2,11 @@ import TaxonWorks from '../../services/TaxonWorks' import { useOtuPageRequest } from '../../helpers/useOtuPageRequest' export const actionLoadCatalog = { - async loadCatalog(taxonId) { + async loadCatalog(taxonId, { signal }) { this.catalog.isLoading = true const response = await useOtuPageRequest('taxonomy', () => - TaxonWorks.getTaxonNameCitations(taxonId) + TaxonWorks.getTaxonNameCitations(taxonId, { signal }) ) this.catalog = { diff --git a/src/modules/otus/store/actions/loadDistribution.js b/src/modules/otus/store/actions/loadDistribution.js deleted file mode 100644 index 8550194..0000000 --- a/src/modules/otus/store/actions/loadDistribution.js +++ /dev/null @@ -1,56 +0,0 @@ -import { - isRankGrpup, - removeDuplicateShapes, - makeGeoJSONFeature -} from '../../utils' -import TaxonWorks from '../../services/TaxonWorks' -import { useOtuPageRequest } from '../../helpers/useOtuPageRequest' - -export const actionLoadDistribution = { - async loadDistribution({ otuId, rankString }) { - const isSpeciesGroup = rankString && isRankGrpup('SpeciesGroup', rankString) - - const getAggregateShape = async (otuId) => { - useOtuPageRequest('panel:map', () => TaxonWorks.getOtuDistribution(otuId)) - .then(({ data }) => { - const geojson = JSON.parse(data.cached_map.geo_json) - - this.distribution.currentShapeTypes = ['Aggregate'] - this.distribution.geojson = { - features: [makeGeoJSONFeature(geojson, 'Aggregate')] - } - - this.loadCachedMap(data.cached_map.id) - }) - .catch((e) => { - this.distribution.errorMessage = e.response.data.error - this.distribution.currentShapeTypes = [] - this.distribution.geojson = [] - }) - } - - if (isSpeciesGroup) { - useOtuPageRequest('panel:map', () => - TaxonWorks.getOtuGeoJSONDistribution(otuId) - ) - .then(({ data }) => { - if (data.request_too_large) { - this.distribution.geojson = null - this.distribution.errorMessage = data.message - } else { - const { features, shapeTypes } = removeDuplicateShapes(data) - - this.distribution.currentShapeTypes = shapeTypes - this.distribution.geojson = { - features - } - } - }) - .catch((e) => { - getAggregateShape(otuId) - }) - } else { - getAggregateShape(otuId) - } - } -} diff --git a/src/modules/otus/store/actions/loadTaxonomy.js b/src/modules/otus/store/actions/loadTaxonomy.js index 620832b..87e5798 100644 --- a/src/modules/otus/store/actions/loadTaxonomy.js +++ b/src/modules/otus/store/actions/loadTaxonomy.js @@ -1,10 +1,13 @@ import TaxonWorks from '../../services/TaxonWorks' export const actionLoadTaxonomy = { - async loadTaxonomy(otuId) { + async loadTaxonomy(otuId, { signal }) { const { data } = await TaxonWorks.getTaxonomy(otuId, { - max_descendants_depth: 0, - extend: ['common_names'] + params: { + max_descendants_depth: 0, + extend: ['common_names'] + }, + signal }) this.taxonomy = { diff --git a/src/modules/otus/store/store.js b/src/modules/otus/store/store.js index 5be2d02..52cd5ca 100644 --- a/src/modules/otus/store/store.js +++ b/src/modules/otus/store/store.js @@ -3,7 +3,6 @@ import TaxonWorks from '../services/TaxonWorks' import { useOtuPageRequest } from '../helpers/useOtuPageRequest' import { useOtuPageRequestStore } from './request' import { - actionLoadDistribution, actionLoadCatalog, actionLoadTaxonomy, actionLoadCachedMap @@ -15,12 +14,6 @@ export const useOtuStore = defineStore('otuStore', { otu: null, taxon: null, images: null, - distribution: { - geojson: null, - errorMessage: null, - currentShapeTypes: [], - cachedMap: null - }, catalog: { sources: [], stats: {}, @@ -34,51 +27,39 @@ export const useOtuStore = defineStore('otuStore', { } }, actions: { - async loadTaxon(id) { + async loadTaxon(id, { signal }) { const taxon = await useOtuPageRequest('summary', () => - TaxonWorks.summary(id) + TaxonWorks.summary(id, { signal }) ) this.taxon = taxon.data }, - async loadOtu(id) { - const otu = await TaxonWorks.getOtu(id) + async loadOtu(id, { signal }) { + const otu = await TaxonWorks.getOtu(id, { signal }) this.otu = otu.data }, - async loadInit(otuId) { + async loadInit({ otuId, controller }) { const requestStore = useOtuPageRequestStore() + const { signal } = controller requestStore.$reset() try { - await this.loadOtu(otuId) - await this.loadTaxon(this.otu.taxon_name_id) + await this.loadOtu(otuId, { signal }) + await this.loadTaxon(this.otu.taxon_name_id, { + signal + }) + await this.loadCatalog(this.otu.taxon_name_id, { + signal + }) + await this.loadTaxonomy(otuId, { signal }) } catch (error) { - return false + return Promise.reject(error) } - - await this.loadCatalog(this.otu.taxon_name_id) - await this.loadTaxonomy(otuId) - - return true - }, - - async loadImages(otuId) { - const params = { - extend: ['depictions', 'attribution', 'source', 'citations'], - otu_scope: ['all'] - } - - this.images = ( - await useOtuPageRequest('panel:images', () => - TaxonWorks.getOtuImages(otuId, params) - ) - ).data }, - ...actionLoadDistribution, ...actionLoadCatalog, ...actionLoadTaxonomy, ...actionLoadCachedMap diff --git a/src/modules/otus/store/useDistributionStore.js b/src/modules/otus/store/useDistributionStore.js new file mode 100644 index 0000000..263ba33 --- /dev/null +++ b/src/modules/otus/store/useDistributionStore.js @@ -0,0 +1,96 @@ +import TaxonWorks from '../services/TaxonWorks' +import { defineStore } from 'pinia' +import { useOtuPageRequest } from '../helpers/useOtuPageRequest' +import { RESPONSE_ERROR } from '../constants' +import { + isRankGrpup, + removeDuplicateShapes, + makeGeoJSONFeature +} from '../utils' + +export const useDistributionStore = defineStore('distributionStore', { + state: () => { + return { + distribution: { + geojson: null, + errorMessage: null, + currentShapeTypes: [], + cachedMap: null + }, + controller: null + } + }, + actions: { + resetRequest() { + this.controller?.abort() + }, + + loadCachedMap(mapId) { + TaxonWorks.getCachedMap(mapId, { signal: this.controller.signal }).then( + (response) => { + this.distribution.cachedMap = response.data + } + ) + }, + + async getAggregateShape(otuId) { + useOtuPageRequest('panel:map', () => + TaxonWorks.getOtuDistribution(otuId, { + signal: this.controller.signal + }) + ) + .then(({ data }) => { + const geojson = JSON.parse(data.cached_map.geo_json) + + this.distribution.currentShapeTypes = ['Aggregate'] + this.distribution.geojson = { + features: [makeGeoJSONFeature(geojson, 'Aggregate')] + } + + this.loadCachedMap(data.cached_map.id) + }) + .catch((e) => { + if (e.name != RESPONSE_ERROR.CanceledError) { + this.distribution.errorMessage = e.response.data.error + this.distribution.currentShapeTypes = [] + this.distribution.geojson = [] + } + }) + }, + + async loadDistribution({ otuId, rankString }) { + const isSpeciesGroup = + rankString && isRankGrpup('SpeciesGroup', rankString) + + this.controller = new AbortController() + + if (isSpeciesGroup) { + useOtuPageRequest('panel:map', () => + TaxonWorks.getOtuGeoJSONDistribution(otuId, { + signal: this.controller.signal + }) + ) + .then(({ data }) => { + if (data.request_too_large) { + this.distribution.geojson = null + this.distribution.errorMessage = data.message + } else { + const { features, shapeTypes } = removeDuplicateShapes(data) + + this.distribution.currentShapeTypes = shapeTypes + this.distribution.geojson = { + features + } + } + }) + .catch((e) => { + if (e.name !== RESPONSE_ERROR.CanceledError) { + this.getAggregateShape(otuId) + } + }) + } else { + this.getAggregateShape(otuId) + } + } + } +}) diff --git a/src/modules/otus/store/useImageStore.js b/src/modules/otus/store/useImageStore.js new file mode 100644 index 0000000..f6d9aef --- /dev/null +++ b/src/modules/otus/store/useImageStore.js @@ -0,0 +1,44 @@ +import TaxonWorks from '../services/TaxonWorks' +import { defineStore } from 'pinia' +import { useOtuPageRequest } from '../helpers/useOtuPageRequest' +import { RESPONSE_ERROR } from '../constants' + +export const useImageStore = defineStore('imageStore', { + state: () => { + return { + images: null, + controller: null + } + }, + + actions: { + resetRequest() { + this.controller?.abort() + }, + + async loadImages(otuId) { + const params = { + extend: ['depictions', 'attribution', 'source', 'citations'], + otu_scope: ['all'] + } + + this.controller = new AbortController() + + try { + const response = await useOtuPageRequest('panel:images', () => + TaxonWorks.getOtuImages(otuId, { + params, + signal: this.controller.signal + }) + ) + + this.images = response.data + this.controller = null + } catch (e) { + if (e.name !== RESPONSE_ERROR.CanceledError) { + this.controller = null + } + } + } + } +}) diff --git a/src/modules/otus/views/Index.vue b/src/modules/otus/views/Index.vue index bd2c742..a816ec9 100644 --- a/src/modules/otus/views/Index.vue +++ b/src/modules/otus/views/Index.vue @@ -89,6 +89,7 @@ import SiteMap from '../components/SiteMap.vue' import Breadcrumb from '../components/Breadcrumb/Breadcrumb.vue' import TaxaInfo from '../components/TaxaInfo.vue' import DWCDownload from '../components/DWCDownload.vue' +import { RESPONSE_ERROR } from '../constants' //import useChildrenRoutes from '../composables/useChildrenRoutes' @@ -97,6 +98,7 @@ const router = useRouter() const routeParams = ref(route.params) const tabs = [] // useChildrenRoutes() const store = useOtuStore() +let controller = new AbortController() router.afterEach((route) => { routeParams.value = route.params @@ -104,7 +106,6 @@ router.afterEach((route) => { const otu = computed(() => store.otu) const taxon = computed(() => store.taxon) - const isReady = computed(() => otu.value?.id && taxon.value?.id) onServerPrefetch(async () => { @@ -114,12 +115,14 @@ onServerPrefetch(async () => { watch( () => route.fullPath, async () => { + controller.abort() + controller = new AbortController() loadInitialData() } ) onMounted(async () => { - if (!otu.value || otu.value.id !== Number(route.params.id)) { + if (otu.value?.id !== Number(route.params.id) || !taxon.value?.id) { await loadInitialData() } else { updateMetadata() @@ -132,12 +135,17 @@ onBeforeUnmount(() => { async function loadInitialData() { store.$reset() - const success = await store.loadInit(route.params.id) - if (success) { + try { + await store.loadInit({ + otuId: route.params.id, + controller + }) updateMetadata() - } else { - router.replace({ name: 'notFound' }) + } catch (e) { + if (e.name !== RESPONSE_ERROR.CanceledError) { + router.replace({ name: 'notFound' }) + } } } From 49cb7389d6f0e1171365395a8f8b2564f84a766a Mon Sep 17 00:00:00 2001 From: jlpereira Date: Sun, 20 Aug 2023 00:07:21 -0300 Subject: [PATCH 2/2] Update prop --- src/modules/otus/components/Panel/PanelContent/PanelContent.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/otus/components/Panel/PanelContent/PanelContent.vue b/src/modules/otus/components/Panel/PanelContent/PanelContent.vue index e2938b4..df4d7c9 100644 --- a/src/modules/otus/components/Panel/PanelContent/PanelContent.vue +++ b/src/modules/otus/components/Panel/PanelContent/PanelContent.vue @@ -18,7 +18,7 @@ import ContentTopic from './PanelContentTopic.vue' const props = defineProps({ otuId: { type: Number, - default: undefined + required: true } })