Search code examples
mapboxmapbox-gl-jsmapbox-glmapbox-markerwebflow

Error with Mapbox GL integration when adding markers: "Cannot read property 'coordinates' of undefined"


I've been working on creating a dynamically updated Mapbox GL integration inside Webflow's CMS. I've succeeded in creating an array of features that can be read by Mapbox's API, but these features won't show on the map because the coordinates are not being read by the function that creates the map markers.

I receive the following error Cannot read property 'coordinates' of undefined at map-test-page:139 which is where a longitude and latitude is assigned to the current marker via this line: .setLngLat(marker.geometry.coordinates)

Partial solution was found here, but the code I've integrated into my site doesn't have featuresIn or featuresAt functions which seem to be the only way to include a includeGeometry: true parameter.

I'm curious if I need to rethink how I've created markers and do something with a function like map.on('click', ...) reference here.

Here is a minimal version that reproduces my issue.

If you're familiar with the Webflow interface you can view a read-only version of the site.

Any help would be greatly appreciated!

Here is the Mapbox script I'm using on the page:

 var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/strawpari/ckp2nu3dw6cwu17nt4kqwf1vv',
    center: [-13.723969, 48.360542],
        zoom: 2,
        pitch: 0,
        bearing: 0,
        antialias: true,
        interactive: true
  });

var geojson = {
  type: 'FeatureCollection',
  features: farmerArray,
};

// add markers to map
geojson.features.forEach(function(marker) {

  // create a HTML element for each feature
  var el = document.createElement('div');
  el.className = 'marker';

  // make a marker for each feature and add to the map
  new mapboxgl.Marker(el)
    .setLngLat(marker.geometry.coordinates)
        .setPopup(new mapboxgl.Popup({ offset: 25 }) // add popups
    .setHTML('<img src=\'' + marker.properties.image + '\' width=\'50\' height=\'50\' border-radius=\'50%\'>' + '<h3>' + marker.properties.title + '</h3><p>' + marker.properties.description + '</p>'))
    .addTo(map);
});

And here is the code embedded in each CMS item that adds a farmer's information to the farmerArray which is being read by Mapbox. Text in double-quotations "" is a placeholder for the dynamic information populated by the CMS.

var farmerArrayItem = 
JSON.stringify({
   type: 'Feature',
   geometry: {
      type: 'Point',
      coordinates: ["longitude", "latitude"]
   },
   properties: {
      title: "name",
      description: "text",
      image: "imagepath"
  }
});

farmerArray.push(farmerArrayItem);

Solution

  • It doesn't appear that you have tried using the Developer Tools to debug your code. That's definitely a skill you should pick up.

    With the dev tools, you will quickly see that the value of marker at the critical point is a string:

    enter image description here

    So you just need to use JSON.parse:

    geojson.features.forEach(function(markerString) {
      const marker = JSON.parse(markerString);
    
      // create a HTML element for each feature
      var el = document.createElement('div');
      el.className = 'marker';
    
      // make a marker for each feature and add to the map
      new mapboxgl.Marker(el)
        .setLngLat(marker.geometry.coordinates)