Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Markers position not refreshing #35

Closed
polsola opened this issue Nov 25, 2019 · 6 comments
Closed

Markers position not refreshing #35

polsola opened this issue Nov 25, 2019 · 6 comments

Comments

@polsola
Copy link

polsola commented Nov 25, 2019

Hello! I'm using custom markers and I'm trying to refresh the position every X seconds, currently I've faked it with a timeOut like this:

<template>
<div>
  <GmapMap
    :center="center"
    :zoom="8"
    style="width: 100%; height: 600px"
    >
    <gmap-custom-marker 
        :key="vehicle.id"
        v-for="vehicle in vehicles"
        :marker="vehicle.position"
    >
        <div class="vehicle-marker">
            <img :src="vehicle.avatar" />
        </div>
    </gmap-custom-marker> 
</GmapMap>
</div>
</template>

<style lang="scss">

.vehicle-marker {
    img {
        width: 64px;
        display: block;
    }
}
    
</style>

<script>
export default {
    layout: 'default',
    data() {
        return {
            center: {lat:41.385063, lng:2.173404},
            vehicles: [
                {
                    id: 1,
                    avatar: '##',
                    position: {
                        lat: 41.385063,
                        lng: 2.173404
                    }
                },{
                    id: 2,
                    avatar: '##',
                    position: {
                        lat: 41.930290,
                        lng: 2.254350
                    }
                }
            ]
        }
    },
    mounted() {
        setInterval(function () {
            this.vehicles.forEach(vehicle => {
                var newLat = vehicle.position.lat += (Math.floor(Math.random() * 11) >= 6) ? 0.005 : -0.005
                var newLng = vehicle.position.lng += (Math.floor(Math.random() * 11) >= 6) ? 0.005 : -0.005
                console.log('Vehicle', vehicle.id, newLat, newLng)
                vehicle.position.lat = newLat
                vehicle.position.lng = newLng
            });
            }.bind(this), 2000)
    }
}
</script>

This code works with default markers but custom ones seems not to refresh, it's maybe because I'm using Nuxt.js? I'm importing the library with a plugin and ssr: false to avoid errors

@eregnier
Copy link
Owner

eregnier commented Dec 17, 2019

Hey polsola.
I saw your issue just now, sorry.
I don't know a lot nuxt, but indeed it seems there is issues related to nuxt due to the underlaying gmap library of this component. there is a small trick in the link on the README that gives a hint how to solve it. I cannot do any thing more for you on this topic.

image

Please let me know if this solves your issue.

@eregnier
Copy link
Owner

I also thing you issue may be due to SSR that doesn't compute marker on gmap properly.
You may try to render them on client side for a test and if it is related to SSR, you may share me any technical detail that would help to solve your issue.

@polsola
Copy link
Author

polsola commented Dec 18, 2019

Hello Eric,
Do not worry, thanks for the help!
I've tried now to import it without plugin and with the workaround, with this there's no error, but the position still doesn't refresh, here's how it looks now:

<template>
<div>
  <GmapMap
    :center="center"
    :zoom="8"
    style="width: 100%; height: 600px"
    >
    <gmap-custom-marker 
        :key="vehicle.id"
        v-for="vehicle in vehicles"
        :marker="vehicle.position"
    >
        <div class="vehicle-marker">
            <img :src="vehicle.avatar" />
        </div>
    </gmap-custom-marker> 
</GmapMap>
</div>
</template>

<style lang="scss">

.vehicle-marker {
    width: 100px;
    height: 100px;
    background-color: red;
    img {
        width: 64px;
        display: block;
    }
}
    
</style>

<script>

import * as VueGoogleMaps from 'vue2-google-maps'
import GmapCustomMarker from 'vue2-gmap-custom-marker'
import Vue from 'vue'

Vue.use(VueGoogleMaps, {
  load: {
    key: '#'
  }
})

export default {
    layout: 'ridereact',
    components: {
      'gmap-custom-marker': GmapCustomMarker
    },
    head() {
        return {
        title: `${this.$t('menu.map')}`,
        }
    },
    data() {
        return {
            center: {lat:41.385063, lng:2.173404},
            vehicles: [
                {
                    id: 1,
                    avatar: '#',
                    position: {
                        lat: 41.385063,
                        lng: 2.173404
                    }
                },{
                    id: 2,
                    avatar: '#',
                    position: {
                        lat: 41.930290,
                        lng: 2.254350
                    }
                }
            ]
        }
    },
    mounted() {
        setInterval(function () {
            this.vehicles.forEach(vehicle => {
                var newLat = vehicle.position.lat += (Math.floor(Math.random() * 11) >= 6) ? 0.005 : -0.005
                var newLng = vehicle.position.lng += (Math.floor(Math.random() * 11) >= 6) ? 0.005 : -0.005
                
                vehicle.position.lat = newLat
                vehicle.position.lng = newLng
                console.log('Vehicle', vehicle.id, vehicle.position.lat, vehicle.position.lng)
            });
            }.bind(this), 2000)
    }
}
</script>

I'm gonna try to create the same without Nuxt.js to see if this works as expected

@polsola
Copy link
Author

polsola commented Dec 18, 2019

Hello again Eric,

Weird thing, if I set both of the markers (normal & custom) the position updates correctly on both, here's the template now:

  <GmapMap
    :center="center"
    :zoom="8"
    style="width: 100%; height: 600px"
    >
    <GmapMarker 
        :key="`vehicle-${vehicle.id}`"
        v-for="vehicle in vehicles"
        :position="vehicle.position"
     />
    <gmap-custom-marker 
        :key="vehicle.id"
        v-for="vehicle in vehicles"
        :marker="vehicle.position"
        :offsetY="-10"
    >
        <div class="vehicle-marker">
            <img :src="vehicle.avatar" />
        </div>
    </gmap-custom-marker> 
</GmapMap>

@eregnier
Copy link
Owner

eregnier commented Jan 7, 2020

I am back from holiday, I'll have a look into your issue soon.

@eregnier
Copy link
Owner

Hey @polsola ,

Here is a working code

<template>
    <div>
        {{vehicles}}
        <GmapMap :center="center" :zoom="8" style="width: 100%; height: 600px">
            <gmap-custom-marker
                :key="vehicle.id"
                v-for="vehicle in vehicles"
                :marker="vehicle.position"
            >
                <div class="vehicle-marker">
                    <img :src="vehicle.avatar" />
                </div>
            </gmap-custom-marker>
        </GmapMap>
    </div>
</template>

<style>
.vehicle-marker {
    width: 100px;
    height: 100px;
    background-color: red;
}
.vehicle-marker img {
    width: 64px;
    display: block;
}
</style>

<script>
import * as VueGoogleMaps from "vue2-google-maps";
import GmapCustomMarker from "vue2-gmap-custom-marker";
import Vue from "vue";

Vue.use(VueGoogleMaps, {
    load: {
        key: '#'
    }
});

export default {
    layout: "ridereact",
    components: {
        "gmap-custom-marker": GmapCustomMarker
    },
    head() {
        return {
            title: `${this.$t("menu.map")}`
        };
    },
    data() {
        return {
            center: { lat: 41.385063, lng: 2.173404 },
            vehicles: [
                {
                    id: 1,
                    avatar: "#",
                    position: {
                        lat: 41.385063,
                        lng: 2.173404
                    }
                },
                {
                    id: 2,
                    avatar: "#",
                    position: {
                        lat: 41.93029,
                        lng: 2.25435
                    }
                }
            ]
        };
    },
    mounted() {
        setInterval(
            function() {
                this.vehicles.forEach(vehicle => {
                    var newLat = vehicle.position.lat +(Math.floor(Math.random() * 11) >= 6 ? 0.05 : -0.05)
                    var newLng = vehicle.position.lng + (Math.floor(Math.random() * 11) >= 6 ? 0.05 : -0.05)

                    vehicle.position = {
                        lat: newLat,
                        lng: newLng
                    }
                    console.log(
                        "Vehicle",
                        vehicle.id,
                        vehicle.position.lat,
                        vehicle.position.lng
                    );
                });
            }.bind(this),
            2000
        );
    }
};
</script>

I just assigned an object reference to the marker position instead of setting individual raw position number values. This let vue reactive system continue to work properly.

Also, don't forget to clean your set interval in a vue destroy method for exemple if you want to avoid strange behaviors and memory leaks.

Hope this helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants