Reputation: 146
I am trying to create multiple markers in Vue using VueMapbox. Currently the map displays correctly but there is only one marker. I think there is something wrong either with my v-for statement or perhaps in the forEach statement. I am trying to place a marker on each location but only the first location is added.
Here is the code for my vue component:
<template>
<MglMap
:accessToken="accessToken"
:mapStyle.sync="mapStyle"
>
<MglMarker v-for="coordinate in coordinates" :key="coordinate" :coordinates="coordinates">
<MglPopup>
<VCard>
<div>{{ country }}</div>
<div>{{ cases }}</div>
</VCard>
</MglPopup>
</MglMarker>
</MglMap>
</template>
<script>
import Mapbox from "mapbox-gl";
import { MglMap, MglPopup, MglMarker } from "vue-mapbox"
export default {
name: 'Map',
components: {
MglMap,
MglPopup,
MglMarker,
},
data() {
return {
accessToken: 'pk.accesstoken...blahblahblah',
mapStyle: 'mapbox://styles/mapbox/dark-v10',
coordinates: [],
country: '',
cases: 0,
}
},
created() {
this.mapbox = Mapbox;
this.getData();
},
methods: {
getData: function () {
fetch('https://coronavirus-tracker-api.herokuapp.com/v2/locations')
.then(response => response.json())
.then(data => {
const locations = data.locations;
locations.forEach(stat => {
const country = stat.country;
this.country = country;
const cases = stat.latest.confirmed;
this.cases = cases;
const coordinates = [stat.coordinates.longitude, stat.coordinates.latitude]
this.coordinates = coordinates;
})
})
}
}
}
</script>
Upvotes: 1
Views: 1620
Reputation: 90028
You're currently doing a v-for
on coordinates. It should be on locations
.
If locations
don't have all the required props a MglMarker needs, transform them in the forEach
but that's all you should do in that forEach
(if you need it at all). Don't use it to populate this.country
, this.cases
or this.coordinates
. You only want to set those when a marker is clicked (if, and only if, you have any functionality listening to changes on those Vue instance properties).
There might be more details which need to be fixed but, without a minimal reproducible example it's very difficult to spot them. Note: you'll need to create a mapbox public token with readonly permissions for your example to work.
To summarize: Move the functionality from your forEach
into a function called showMarker
or activateMarker
. Call that function whenever a marker is clicked or, if that's what you want, call it on one of the locations to make it the currently active one.
What your code does now is: it makes all markers the currently active one, therefore only the last one iterated will be currently active.
Here's what your MglMarker iterator might look like:
<MglMarker v-for="(l, key) in locations"
:key="key"
:coordinates="l.coordinates"
@click="activateMarker(l)"
>
<MglPopup>
VCard>
<div>{{ l.country }}</div>
<div>{{ l.latest.confirmed }}</div>
</VCard>
</MglPopup>
</MglMarker>
In activateMarker
method you can dispatch any action to let the rest of the app know about your selection. Or you can close any other open popups, for example (although that can be handled easier with :closeOnClick="true"
on each MglPopup).
Upvotes: 2