Search code examples
ruby-on-railsjsonajaxmapboxgeojson

Mapbox GL JS Rails - Load GEOJSON array to markers


I am trying to integrate Mapbox into a static page, but I am having difficulty feeding the geojson array into Mapbox to generate markers procedurally. My ajax call isn’t giving an error message, but none of the geojson data appears in the console and no markers are rendered to the map. When I place some inline geojson in place of my geojson, the markers generate on the map without any problems. Any thoughts on what I have wrong here?

static_pages_controller.rb

    class StaticPagesController < ApplicationController

      def map

        @experiences = Experience.all
        @geojson = Array.new

        @experiences.each do |experience|
          @geojson << {
            type: 'Feature',
            geometry: {
              type: 'Point',
              coordinates: [experience.longitude, experience.latitude]
            },
            properties: {
              name: experience.name,
              address: experience.location,
              :'marker-color' => '#00607d',
              :'marker-symbol' => 'circle',
              :'marker-size' => 'medium'
            }
          }
        end

        respond_to do |format|
          format.html
          format.json { render json: @geojson }  # respond with the created JSON object
        end

      end

static_pages/map.html.erb

    <div id='map' style='width: 100%; height: 750px;'></div>
    <script>

    $(function() {
      mapboxgl.accessToken = 'pk.eyJ1IjoianJvY2tldGxhYiIsImEiOiJTOFhPc1hjIn0.jf1Gd5AeO6xVQoTA_KMhEg';
      var map = new mapboxgl.Map({
          container: 'map',
          style: 'mapbox://styles/mapbox/light-v9',
          center: [-96, 37.8],
          zoom: 3
      });

      map.on('load', function() {
        $.ajax({
          dataType: 'text',
          url: '/map.json',
          success: function(data) {
            var geojson;
            geojson = $.parseJSON(data);
            return geojson;
            // 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)
              .addTo(map);
            });
          },
          error:function() {
              alert("Could not load the events");
            },
        });
      });
    });
    </script>

Server Log

    Started GET "/map.json" for 127.0.0.1 at 2018-02-06 16:07:27 -0800
    Processing by StaticPagesController#map as JSON
      Experience Load (0.3ms)  SELECT "experiences".* FROM "experiences"
    Completed 200 OK in 3ms (Views: 1.4ms | ActiveRecord: 0.3ms)

Solution

  • I ended up figuring it out! I needed to move some of the javascript around for the geojson to be fed correctly and wait for document ready and for the map to load before trying to load the markers and geojson.

    Updated Javascript

        $(function() {
          mapboxgl.accessToken = 'pk.eyJ1IjoianJvY2tldGxhYiIsImEiOiJjajZuNnh5dm4wNTgyMndvMXNqY3lydjI4In0.gHVskGK1QuUoxm8sMwugWQ';
          var map = new mapboxgl.Map({
              container: 'map',
              style: 'mapbox://styles/jrocketlab/cjdaqnwhbb3e52sqwblieddk1',
              center: [-96, 37.8],
              zoom: 3
          });
    
          map.on('load', function() {
    
            $.ajax({
              dataType: 'text',
              url: '/map.json',
              success: function(data) {
                var myjson;
                myjson = $.parseJSON(data);
                var geojson = {
                  type: 'FeatureCollection',
                  features: myjson
                };
    
                // 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)
                  .addTo(map);
                });
              },
              error:function() {
                  alert("Could not load the events");
                }
            });
    
    
          });
        });