Closed tlhunter closed 2 years ago
~Actually, it looks like this may be an issue on my end?~
~With my application, I'm migrating from regular Marker
elements to CustomMarker
elements. One thing I was doing was sorting the elements immediately after updating the array. This is because the array was used both to display Marker elements and a list of descriptive text elements.~
~When I remove the array sorting code, the bug goes away. It seems that the Marker
elements don't mind being sorted, but that CustomMarker
do mind. I no longer need to sort the markers so I'm removing the code and my problem is gone. I'll leave this issue open for now for a repo owner to look at just in case the difference in behaviors between Marker
and CustomMarker
is considered a bug.~
I spoke too soon. Removing the array sorting code did fix that one particular instance. However, this same error stack trace is still present in other situations. I think the error is only thrown with certain combinations of markers changing order and being redrawn.
Even in more complex situations where I get the error it can still be alleviated by randomizing the id of the custom marker.
Can you share a minmial reproduction @tlhunter? You can use vite.new/vue
@tlhunter I haven't encountered issues with StackBlitz before but you can alternatively share a CodeSandbox or a link to a repo
@HusamIbrahim I think I had encountered a bug with StackBlitz where the node_modules directory was initially created but was blown away upon registering an account... But, I was able to get a reproduction working.
As an overview: The code draws a map with 200 custom markers on it. Every five seconds it removes a marker from the list of rendered markers then adds it back a second later. Note that it does so using .shift()
and .unshift()
, meaning the first element in the list is modified, more on that later.
The first visible issue is that of performance. When the marker is removed and added again, every single map marker cluster performs a slow redraw. On my machine it visually appears to take around 300ms. If you have a very fast development machine you might not notice it. Here's a recording of this happening just in case:
I would like to add that this performance issue doesn't happen without clusters. This can be seen by deleting the wrapping <MarkerCluster>
element. It makes me think that without clusters the keys/IDs of the markers are used for repainting, so that if an element still exists it's not repainted. However, with clusters, it's as if a parent cluster doesn't have a key/ID, and everything is blown away and rendered again.
The second issue is the one that is the original subject of this ticket, wherein the modifications of the map markers triggers an error. To trigger this error I'll zoom in twice then start dragging and dropping the screen around. It's not always consistent (it might depend on the layout of the randomly generated pins) but after a few tries I always get it to happen.
One thing that's interesting is that if I change the shift and unshift to .pop()
and .push()
, then the issue seems to go away. This makes me think it might have something to do with the first of an array of elements being removed, and maybe some DOM operation is trying to insert an element before the parent array of elements.
These errors happen even when the <MarkerCluster>
is removed. They also don't happen with regular <Marker>
elements.
Here's a copy paste of the code from the stack for visibility. Note that the key is whitelisted to this exact stack blitz domain and won't work anywhere else.
<template>
<GoogleMap
ref="mapRef"
api-key="AIzaSyCiIWyc0xzdsrkZeBsHOjwwXbk_ipA1V7A"
style="width: 100%; height: 100%"
:center="center"
:zoom="12"
>
<CustomMarker
:options="{
anchorPoint: 'LEFT_CENTER',
position: userLocation,
}"
>👩 User Position</CustomMarker
>
<MarkerCluster>
<CustomMarker
v-for="marker in markers"
v-bind:key="marker.id"
:options="{ anchorPoint: 'LEFT_CENTER', position: marker.pos }"
>👽 Foo #{{ marker.id }}</CustomMarker
>
</MarkerCluster>
</GoogleMap>
</template>
<script>
import { defineComponent, ref } from 'vue';
import { GoogleMap, CustomMarker, MarkerCluster } from 'vue3-google-map';
const BASE_LAT = 40.689247;
const BASE_LNG = -74.044502;
export default defineComponent({
components: { GoogleMap, CustomMarker, MarkerCluster },
setup() {
const mapRef = ref(null);
const markers = ref([]);
for (let i = 0; i < 200; i++) {
const marker = {
id: i,
pos: {
lat: BASE_LAT + (Math.random() - 0.5) * 0.1,
lng: BASE_LNG + (Math.random() - 0.5) * 0.1,
},
};
markers.value.push(marker);
}
const center = { lat: 40.689247, lng: -74.044502 };
const userLocation = ref({
lat: 40.689247,
lng: -74.044502,
});
setInterval(() => {
const m = markers.value.shift();
//const m = markers.value.pop();
setTimeout(() => {
markers.value.unshift(m);
//markers.value.push(m);
}, 1000);
}, 5000);
/*
setInterval(() => {
let randomId = Math.floor(Math.random() * 200);
markers.value[randomId].lat += Math.random() - 0.5;
markers.value[randomId].lng += Math.random() - 0.5;
}, 10);
setInterval(() => {
userLocation.value.lat += 0.001;
userLocation.value.lng += 0.001;
mapRef.value?.map.panTo(userLocation.value);
}, 1000);
*/
return { center, markers, userLocation, mapRef };
},
});
</script>
<style>
body,
html,
#app {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
Thanks for the repro and detailed report @tlhunter. I'll hopefully take a closer look in the coming days.
This should be fixed in v0.13.1
. Let me know if the issue persists or if you encounter other issues.
vue: 3.2.6 and 3.2.7 vue3-google-map: 0.13.0
I'm having an interesting issue with
CustomMarker
s when altering a list of them and displaying them on a map. In certain situations they will throw an error when being redrawn. In my app's case, panning the map makes a network request based on the new location, and marker data is returned from the client. The client then updates an array of locations. That array is used in a<CustomMarker v-for />
.Here's an example of what the code looks like:
In this case
beacons
is an array of objects with an id, message, loc.lat, and loc.lng properties.Here's a recording of this issue happening:
In this recording, two CustomMarkers are added, then they're removed, then they're added again, then one is removed, and upon trying to add the one that was removed again the error is thrown.
Here's the content of the console:
It seems to me like something might be getting cached in Vue or in
vue3-google-map
. If, for example, I modify theid
field of the individual beacon objects and append a random number to them (v-bind:key="'bcn-mrk-' + beacon.id + Math.random()"
), then the issue goes away entirely.