PPLR maps: a map that cannot be built says so instead of throwing

When the map failed to construct (Mapbox with no token, for one), every map view
called map.value.on('load') on null and threw "Cannot read properties of null" in
its mounted hook. All seven map views now stop there and show the shared, translated
"Map unavailable" in their status line.
This commit is contained in:
Doxa Maps 2026-09-27 03:32:52 +00:00
parent 3734cf3882
commit 183bb21589
7 changed files with 42 additions and 0 deletions

View file

@ -53,6 +53,12 @@ async function streamCoverage() {
onMounted(async () => {
await initializeMap()
exposeMap(map.value)
if (!map.value) {
// The map did not construct (e.g. provider=mapbox with no token; useMapInstance logs why). Say so
// and stop: everything below needs a map, and map.value.on() threw into the mounted hook.
status.value = t('messages.mapUnavailable')
return
}
map.value.on('load', async () => {
try {
status.value = t('pplr.status.loadingCoverage')

View file

@ -429,6 +429,12 @@ function popupHtml(p) {
onMounted(async () => {
await initializeMap()
exposeMap(map.value)
if (!map.value) {
// The map did not construct (e.g. provider=mapbox with no token; useMapInstance logs why). Say so
// and stop: everything below needs a map, and map.value.on() threw into the mounted hook.
status.value = t('messages.mapUnavailable')
return
}
if (map.value) {
map.value.addControl(new (glFor(map.value)).NavigationControl({ showCompass: false, visualizePitch: false }), 'bottom-right')
map.value.addControl(new FullscreenToggleControl(profileRoot.value), 'bottom-right')

View file

@ -37,6 +37,12 @@ const { map, isMapReady, initializeMap, destroy } = useMapInstance({
onMounted(async () => {
await initializeMap()
exposeMap(map.value)
if (!map.value) {
// The map did not construct (e.g. provider=mapbox with no token; useMapInstance logs why). Say so
// and stop: everything below needs a map, and map.value.on() threw into the mounted hook.
status.value = t('messages.mapUnavailable')
return
}
map.value.on('load', async () => {
try {
status.value = t('pplr.status.addingPolygons')

View file

@ -247,6 +247,12 @@ function popupHtml(p) {
onMounted(async () => {
await initializeMap()
exposeMap(map.value)
if (!map.value) {
// The map did not construct (e.g. provider=mapbox with no token; useMapInstance logs why). Say so
// and stop: everything below needs a map, and map.value.on() threw into the mounted hook.
status.value = t('messages.mapUnavailable')
return
}
if (map.value) {
map.value.addControl(new (glFor(map.value)).NavigationControl({ showCompass: false, visualizePitch: false }), 'bottom-right')
map.value.addControl(new FullscreenToggleControl(profileRoot.value), 'bottom-right')

View file

@ -396,6 +396,12 @@ function popupHtml(p) {
onMounted(async () => {
await initializeMap()
exposeMap(map.value)
if (!map.value) {
// The map did not construct (e.g. provider=mapbox with no token; useMapInstance logs why). Say so
// and stop: everything below needs a map, and map.value.on() threw into the mounted hook.
status.value = t('messages.mapUnavailable')
return
}
// Navigation: zoom +/- (Mapbox built-in) + custom fullscreen toggle.
// See FullscreenToggleControl in pplrMap.js for why we don't use

View file

@ -45,6 +45,12 @@ const { map, isMapReady, initializeMap, destroy } = useMapInstance({
onMounted(async () => {
await initializeMap()
exposeMap(map.value)
if (!map.value) {
// The map did not construct (e.g. provider=mapbox with no token; useMapInstance logs why). Say so
// and stop: everything below needs a map, and map.value.on() threw into the mounted hook.
status.value = t('messages.mapUnavailable')
return
}
map.value.on('load', async () => {
try {
status.value = t('pplr.status.loadingPgData')

View file

@ -59,6 +59,12 @@ const DATA_SOURCES = [
onMounted(async () => {
await initializeMap()
exposeMap(map.value)
if (!map.value) {
// The map did not construct (e.g. provider=mapbox with no token; useMapInstance logs why). Say so
// and stop: everything below needs a map, and map.value.on() threw into the mounted hook.
status.value = t('messages.mapUnavailable')
return
}
if (map.value) {
map.value.addControl(new (glFor(map.value)).NavigationControl({ showCompass: false, visualizePitch: false }), 'bottom-right')
map.value.addControl(new FullscreenToggleControl(profileRoot.value), 'bottom-right')