Creating map using Leaflet & Vue.js
You have hit a race condition here. The mounted()
hook is called before the axios.get
asynchronous call have been completed.
The sequence of calls is probably this 1.created()
, 2.mounted()
, 3.axios.then()
So, you will need to slightly change your logic so the map is initialized when both the creation has completed and the mount hook has been invoked.
Something like this,
add a flag for the mounted call been executed
data() { return { map: null, mounted: false, latlng: null }
move the map creation code into a method
createMap: function() { this.map = L.map("mapContainer", { center: this.latlng ...
at creation go fetch the data, and if already mounted, create the map
created(){ axios.all([axios.get('http://127.0.0.1:5000/api/get_longitude'); axios.get('http://127.0.0.1:5000/api/get_latitude')]) .then((longresp,latresp)=> { this.latlng=[latresp.data,longresp.data]; if (this.mounted) this.createMap() })
and then at mounted, check if by chance the data is already available, and if not, set the flag for the creation of the map
mounted() { if (this.latlng) this.createMap() this.mounted = true; ...
Create the Map when the data is available ( when axios promise is successful ).
More on promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Use a indicator until content not ready.
I think there is no need for separate requests, so i merged the 2 axios requests. Your backend should return the [lat, long] array.
<template> <div> <!-- I also added a simple loading indicator, obviously you can go for something more fancy like a spinner --!> <p v-if="loading">Loading...</p> <div id="mapContainer">{{ latlng }}</div> </div></template><script> import "leaflet/dist/leaflet.css"; import L from "leaflet"; import axios from 'axios'; export default { name: "Map", data() { return { map: null, loading: false, latlng: [] }; }, methods: { setupLeafletMap: function () { this.map = L.map("mapContainer", { center: this.latlng, zoom: 12, }); L.tileLayer("http://{s}.tile.osm.org/{z}/{x}/{y}.png", { attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' }).addTo(this.map); } }, mounted() { this.loading = true; axios.get('http://127.0.0.1:5000/api/get_latlng').then(res => { this.latlng = res.data; this.setupLeafletMap(); // Creating the Map here ensures that data is already loaded from server side this.loading = false; }).catch(error => console.error(error)); }, beforeDestroy() { if (this.map) { this.map.remove(); } } };</script><style scoped> #mapContainer { width: 50vw; height: 50vh; }</style>