I'm trying to get a plain map of, say, "Madison, WI" or "London, GBR" - I have a Ruby on Rails web app that has a string of the user's location as city, state-code or city, country-code, and I want to pass it to mapbox and get a map of that city. I see ways to let the user type in their location into a search field and get a map, but not a way to get the first "hit" from a search string like the examples above. I created a javascript script that should work in theory but I have an error. The console does indeed print out the contents of the json retrieved from the API (api.mapbox.com), but when I try to put the coordinates into a new geojson object, it fails, stating in the console that "undefined is not an object." Any help would be appreciated.
<div id='map' style='width: 300px; height: 200px;'></div>
<script>
mapboxgl.accessToken = 'MY_ACCESS_TOKEN';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-96, 37.8],
zoom: 3
});
var userData = {};
function saveUserData(input) {
userData = input;
console.log(userData);
}
var partnerData = {};
function savePartnerData(input) {
partnerData = input;
console.log(partnerData);
}
fetch('https://api.mapbox.com/geocoding/v5/mapbox.places/<%= @user.location.strip %>.json?limit=1&access_token=MY_ACCESS_TOKEN')
.then(res => res.json())
.then(data => saveUserData(data));
fetch('https://api.mapbox.com/geocoding/v5/mapbox.places/<%= prayer_partner.location.strip %>.json?limit=1&access_token=MY_ACCESS_TOKEN')
.then(res => res.json())
.then(data => savePartnerData(data));
const geojson = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: userData.features[0].geometry.coordinates
},
properties: {
title: '<%= @user.name %>',
description: '<%= @user.location %>'
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: partnerData.features[0].geometry.coordinates
},
properties: {
title: '<%= prayer_partner.name %>',
description: '<%= prayer_partner.location %>'
}
}
]
};
// add markers to map
for (const feature of geojson.features) {
// create a HTML element for each feature
const el = document.createElement('div');
el.className = 'marker';
// make a marker for each feature and add to the map
new mapboxgl.Marker(el).setLngLat(feature.geometry.coordinates)
.setPopup(
new mapboxgl.Popup({ offset: 25 }) // add popups
.setHTML(
`<h3>${feature.properties.title}</h3><p>${feature.properties.description}</p>`
)
).addTo(map);
}
</script>
And my JavaScript console reads:
[Error] TypeError: undefined is not an object (evaluating 'userData.features[0]')
Global Code (1:175)
[Log] {type: "FeatureCollection", query: ["madison", "wi"], features: Array, attribution: "NOTICE: © 2022 Mapbox and its suppliers. All right…y not be retained. POI(s) provided by Foursquare."} (1, line 150)
[Log] {type: "FeatureCollection", query: ["minot", "nd"], features: Array, attribution: "NOTICE: © 2022 Mapbox and its suppliers. All right…y not be retained. POI(s) provided by Foursquare."} (1, line 157)