Can't read data from json file

I am having a got at a sample I found and can’t figure out what is my issue with the either the Json data format or the way I am trying to read it

The error I am getting is Uncaught TypeError: locations.forEach is not a function

This is how I call my function

        showMap
            (JSON.stringify({
                'type': 'FeatureCollection',
                'features': [
                    {
                        'type': 'Feature',
                        'geometry': {
                            'type': 'Point',
                            'coordinates': [-77.034084142948, 38.909671288923]
                        },
                        'properties': {
                            'phoneFormatted': '(202) 234-7336',
                            'phone': '2022347336',
                            'address': '1471 P St NW',
                            'city': 'Washington DC',
                            'country': 'United States',
                            'crossStreet': 'at 15th St NW',
                            'postalCode': '20005',
                            'state': 'D.C.'
                        }
                    },
                    {
                        'type': 'Feature',
                        'geometry': {
                            'type': 'Point',
                            'coordinates': [-75.20121216774, 39.954030175164]
                        },
                        'properties': {
                            'phoneFormatted': '(215) 386-1365',
                            'phone': '2153861365',
                            'address': '3925 Walnut St',
                            'city': 'Philadelphia',
                            'country': 'United States',
                            'postalCode': '19104',
                            'state': 'PA'
                        }
                    },
                    {
                        'type': 'Feature',
                        'geometry': {
                            'type': 'Point',
                            'coordinates': [-77.043959498405, 38.903883387232]
                        },
                        'properties': {
                            'phoneFormatted': '(202) 331-3355',
                            'phone': '2023313355',
                            'address': '1901 L St. NW',
                            'city': 'Washington DC',
                            'country': 'United States',
                            'crossStreet': 'at 19th St',
                            'postalCode': '20036',
                            'state': 'D.C.'
                        }
                    }
                ]
            }));

This is the function I am calling

   function showMap(pData)
            {
            mapboxgl.accessToken = 'pk.eyJ1Ijoic2FtaGVybWVzIiwiYSI6ImNpbGxjeGhmYzVvMm52bm1jdmx0NmtvbXoifQ.uf5gBnnbU05bnaw7atDu9A';
            let map = new mapboxgl.Map({
            container: 'travel-map',
            style: 'mapbox://styles/mapbox/streets-v9',
            zoom: 3,
            center: [-77.034084142948, 38.909671288923],
            scrollZoom: false,
        });
     
          
                var locations = JSON.parse(pData);
                var features = Array()

                locations.forEach(function (element) {
                    feature = {
                        'type': 'Feature',
                        'geometry': {
                            'type': 'Point',
                            'coordinates': [element.fields.coordinates.lng, element.fields.coordinates.lat]
                        },
                        'properties': {
                            'title': element.title.rendered,
                            'visits': element.fields.number_of_visits
                        }
                    }
                    features.push(feature)
                })

                map.addSource("locations", {
                    "type": "geojson",
                    "data": {
                        "type": "FeatureCollection",
                        "features": features
                    }
                })

                features.forEach(function (marker) {
                    var popup = new mapboxgl.Popup()
                        .setHTML('<div style="padding:0.3rem 0.3rem 0;text-align:center;">'
                            + '<h2 style="font-size:16px;margin:0 0 0.3rem;">' + marker.properties.title + '</h2>'
                            + '<p style="font-size:12px;margin:0;">Visits: ' + marker.properties.visits + '</p></div>');

                    new mapboxgl.Marker()
                        .setLngLat(marker.geometry.coordinates)
                        .setPopup(popup)
                        .addTo(map);
                });

        }

The parsed pData is an object, it’s not an iterable array that you can use the forEach method on.

Is it the features array in there that you are wanting to iterate through instead?

1 Like

What I want is passing an array of to the function and iterate thru them to display them on a map.

{
                        'type': 'Feature',
                        'geometry': {
                            'type': 'Point',
                            'coordinates': [-77.043959498405, 38.903883387232]
                        },
                        'properties': {
                            'phoneFormatted': '(202) 331-3355',
                            'phone': '2023313355',
                            'address': '1901 L St. NW',
                            'city': 'Washington DC',
                            'country': 'United States',
                            'crossStreet': 'at 19th St',
                            'postalCode': '20036',
                            'state': 'D.C.'
                        }
                    }

If it is the features array

Based on the input

const featureCollection = JSON.stringify({
  type: 'FeatureCollection',
  features: [
    {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [-77.034084142948, 38.909671288923]
      },
      properties: {
        phoneFormatted: '(202) 234-7336',
        phone: '2022347336',
        address: '1471 P St NW',
        city: 'Washington DC',
        country: 'United States',
        crossStreet: 'at 15th St NW',
        postalCode: '20005',
        state: 'D.C.'
      }
    },
    {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [-75.20121216774, 39.954030175164]
      },
      properties: {
        phoneFormatted: '(215) 386-1365',
        phone: '2153861365',
        address: '3925 Walnut St',
        city: 'Philadelphia',
        country: 'United States',
        postalCode: '19104',
        state: 'PA'
      }
    },
    {
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [-77.043959498405, 38.903883387232]
      },
      properties: {
        phoneFormatted: '(202) 331-3355',
        phone: '2023313355',
        address: '1901 L St. NW',
        city: 'Washington DC',
        country: 'United States',
        crossStreet: 'at 19th St',
        postalCode: '20036',
        state: 'D.C.'
      }
    }
  ]
})

and then parsing and looping through the features array

const parsedFeatures = JSON.parse(featureCollection).features // the subproperty 'features' is the array

// no need for making an empty array and foreach with push. map will return a new array
const features = parsedFeatures.map(function (feature) {
  const geometry = feature.geometry

  // return an object for each index of the array
  return {
    type: 'Feature',

    geometry: {
      type: 'Point',
      coordinates: [geometry.coordinates[0], geometry.coordinates[1]]
    },

    properties: {
      title: '', // element.title.rendered ?
      visits: 0  // element.fields.number_of_visits ?
    }
  }
})


output: console.dir(features)

Array(3)
  0:
    geometry:
      coordinates: (2) [-77.034084142948, 38.909671288923]
      type: "Point"

    properties: {title: "", visits: 0}
    type: "Feature"

  1:
    geometry:
      coordinates: (2) [-75.20121216774, 39.954030175164]
      type: "Point"

    properties: {title: "", visits: 0}
    type: "Feature"

  2:
    geometry:
      coordinates: (2) [-77.043959498405, 38.903883387232]
      type: "Point"

    properties: {title: "", visits: 0}
    type: "Feature"

length: 3

It’s not clear where element.title.rendered and element.fields.number_of_visits is coming from

Thank you all for helping me solving the issue. They were some others issues that I had to iron out but it is working.

Belows is the code for those how might be interested in displaying Markers on Mapbox. The original code is here . and my running code is here


        showMap(JSON.stringify({
            type: 'FeatureCollection',
            features: [
                {
                    type: 'Feature',
                    geometry: {
                        type: 'Point',
                        coordinates: [-77.034084142948, 38.909671288923]
                    },
                    properties: {
                        phoneFormatted: '(202) 234-7336',
                        phone: '2022347336',
                        address: '1471 P St NW',
                        city: 'Washington DC',
                        country: 'United States',
                        crossStreet: 'at 15th St NW',
                        postalCode: '20005',
                        state: 'D.C.'
                    }
                },
                {
                    type: 'Feature',
                    geometry: {
                        type: 'Point',
                        coordinates: [-75.20121216774, 39.954030175164]
                    },
                    properties: {
                        phoneFormatted: '(215) 386-1365',
                        phone: '2153861365',
                        address: '3925 Walnut St',
                        city: 'Philadelphia',
                        crossStreet: 'at 19th St',
                        country: 'United States',
                        postalCode: '19104',
                        state: 'PA'
                    }
                },
                {
                    type: 'Feature',
                    geometry: {
                        type: 'Point',
                        coordinates: [-77.043959498405, 38.903883387232]
                    },
                    properties: {
                        phoneFormatted: '(202) 331-3355',
                        phone: '2023313355',
                        address: '1901 L St. NW',
                        city: 'Washington DC',
                        country: 'United States',
                        crossStreet: 'at 19th St',
                        postalCode: '20036',
                        state: 'D.C.'
                    }
                }
            ]
        }));

        function showMap(pData) {
            mapboxgl.accessToken = 'pk.eyJ1Ijoic2FtaGVybWVzIiwiYSI6ImNpbGxjeGhmYzVvMm52bm1jdmx0NmtvbXoifQ.uf5gBnnbU05bnaw7atDu9A';
            let map = new mapboxgl.Map({
                container: 'travel-map',
                style: 'mapbox://styles/mapbox/streets-v9',
                zoom: 11,
                center: [-77.034084142948, 38.909671288923]
            });

            map.on('load', function (e) {
            var locations = JSON.parse(pData);
            var features = Array()

            locations.features.forEach(function (element) {
                feature = {
                    'type': 'Feature',
                    'geometry': {
                        'type': 'Point',
                        'coordinates': element.geometry.coordinates
                    },
                    'properties': {
                        'title': element.properties.phoneFormatted,
                        'visits': element.properties.crossStreet
                    }
                }
                features.push(feature)
               
            })

            map.addSource("locations", {
                "type": "geojson",
                "data": {
                    "type": "FeatureCollection",
                    "features": features,
                   
                }
            })

            features.forEach(function (marker) {
                
                var popup = new mapboxgl.Popup()
                    .setHTML('<div style="padding:0.3rem 0.3rem 0;text-align:center;">'
                        + '<h2 style="font-size:16px;margin:0 0 0.3rem;">' + marker.properties.title + '</h2>'
                        + '<p style="font-size:12px;margin:0;">Visits: ' + marker.properties.visits + '</p></div>');
               
                new mapboxgl.Marker()
                    .setLngLat(marker.geometry.coordinates)
                    .setPopup(popup)
                    .addTo(map);
            });

      
            });
        }

1 Like