How do I simply pass a city and state code and/or country code to the mapbox API and get a map of that city?

Viewed 41

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)
0 Answers
Related