Edit 1
Here is the source code on git
I am working on an Ionic-Vue project with Mapbox integration. My issue is that I am unable to update my geojson data source to create markers on the map, the geoJson data is passed in as props. Here is the flow
On APP.vue created hook
- Using capacitor gets user current location.
- .then() make an Axios call to the server to fetch the JSON data
- On success set the data to store via mutation
On Home.vue[parent component for TheMap.vue]
- Computed value called
getGeoJson
which calls the getters to get geojson data from the state saved an earlier step - Bind the
:marker
prop with computed valuegetGeoJson
data on the TheMap component to be sent as a prop. - Listen to the event
$updatedLocation
and call the API action to fetch new geojson data.
On TheMap.vue
- On create Hook call the
createMap()
. - In Method:
createMap()
- Get the user coords again using
capacitorJS
- init the mapbox map and save it to
this.map
variable - add Attribution using
this.map.addControl
this.map.on("load",cb)
inside of cb call.addSource()
& thenaddMarkers()
- Create a new
marker
for the current user and save it to cosntUserLocationMarker
UserLocationMarker.on("dragend",CB)
to emit a event with latest current user location
- Get the user coords again using
Here is the code for the same just putting the script tags rather than the whole.vue file
APP.Vue
export default {
name: "App",
data() {
return {
currentLocation: "",
};
},
created() {
Geolocation.getCurrentPosition()
.then((result) => {
this.currentLocation = [
result.coords.longitude,
result.coords.latitude,
];
this.$store.dispatch(
`lists/${POST_GEOJSON_ACTION}`,
this.currentLocation
);
})
.catch((err) => console.log(err));
},
};
Home.vue
<template>
<the-map :markers="geojson" @updatedLocation="updateMap"></the-map>
</template>
<script>
export default {
name: "Home",
computed: {
getGeoJson() {
return this.$store.getters[`lists/${GET_GEOJSON_GETTER}`];
},
},
methods: {
updateMap(center) {
this.$store.dispatch(`lists/${POST_GEOJSON_ACTION}`, center);
},
},
};
</script>
TheMap.vue
export default {
props: ["markers"],
emits: ["updatedLocation"],
data() {
return {
access_token: process.env.VUE_APP_MAP_ACCESS_TOKEN,
center: [0, 0],
map: {},
};
},
mounted() {
this.createMap();
},
methods: {
async createMap() {
try {
const coords = await Geolocation.getCurrentPosition();
this.center = [coords.coords.longitude, coords.coords.latitude];
mapboxgl.accessToken = this.access_token;
//Map Instance
this.map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/userName/API_KEY",
center: this.center,
zoom: 12,
scrollZoom: true,
});
// Custom Attribution over the map for Branding
this.map.addControl(
new mapboxgl.AttributionControl({
customAttribution: ` © Comapny Name`,
})
);
this.map.on("load", function(e) {
this.map.addSource("places", {
type: "geojson",
data: this.markers,
});
this.addMarkers();
});
const UserLocationMarker = new mapboxgl.Marker({
draggable: true,
})
.setLngLat(this.center)
.addTo(this.map);
UserLocationMarker.on("dragend", async (e) => {
this.center = Object.values(e.target.getLngLat());
this.$emit("updatedLocation", this.center);
});
} catch (err) {
console.log(err);
}
},
addMarkers() {
this.markers.features.forEach(function(marker) {
var el = document.createElement("div");
el.id = "marker-" + marker.properties.id;
el.className = "marker";
new mapboxgl.Marker(el, { offset: [0, -23] })
.setLngLat(marker.geometry.coordinates)
.addTo(this.map);
});
},
},
};
My issue here is that the TheMap.vue
does get undefined
| [{geojson}]
as a prop however it does not load the marker on init or even after the source is changed in the parent component.
What I expect is that the map on Load uses markers prop to build a list of markers if available else show nothing[handle undefined |
null`] And update that marker list if a new set of Data is injected as prop on changed location.