Search code examples
ruby-on-railswebpackturbolinksopenlayers-6

OpenLayers 6 on Rails target.addEventListener is not a function


i start from the scratch to build a Rails 6 Application with Openlayers 6.1.1. with Webpacker and Turbolinks. Many things are working fine, also with turbolinks. But one thing will not work fine: Openlayers. I add openlayers with yarn an it is basically working. So i can create a map as i expected, but i am not able to add a VectorLayer. If i do this i will get a console message with :

 target.addEventListener is not a function

I mean i am importing all required libs. In my application.js

require("@openlayers/pepjs")
require("ol")

In my map.js

import 'ol/ol.css';
import Feature from 'ol/Feature';
import Map from 'ol/Map';
import MVT from 'ol/format/MVT';
import View from 'ol/View';
import GeoJSON from 'ol/format/GeoJSON';
import Circle from 'ol/geom/Circle';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
//import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';

And my map object:

var vectorLayer = new VectorLayer({
    source: new VectorSource({
        url: 'v1/track/journey',
        format: new GeoJSON()
    }),
});


var OSMMap = new TileLayer({
    source: new OSM({
        attributions: [
            '(c) OpenStreetMap'
        ],
        opaque: false,
        url: 'http://10.232.200.17/tiles/osm/{z}/{x}/{y}.png'
    })
});

// OL Test
var map = new Map({
    layers: [
        OSMMapHLC1,
        VectorLayer
    ],

    target: 'map',
    view: new View({
        center: [0, 0],
        zoom: 2
    })
});
  • I tried it without turbolinks
  • I added pepjs
  • I added jquery manually
  • I tried Leaflet. Result VectorLayers an Realtime Plugin working fine.

Hint. I have to use Openlayers not Leaflet.

Many thanks to everyone who can help.

Stacktrace

Regards Marco


Solution

  • thank you so much for your answer. i thinks this was a copy-paste failure from my side. I had try so many things that my code was messed up. So i start from the scratch an now it is working, So i will show my code here:

    It is mandatory to put all imports outside the turbolinks, everything else should be inside the turbolinks load() function:

    import 'ol/ol.css';
    import Feature from 'ol/Feature';
    import Map from 'ol/Map';
    import View from 'ol/View';
    import GeoJSON from 'ol/format/GeoJSON';
    import Circle from 'ol/geom/Circle';
    import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
    import { OSM, Vector as VectorSource } from 'ol/source';
    import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style';
    //import { toPng } from 'html-to-image';
    
    
    
    $(document).on('turbolinks:load', function() {
    
    
        var exportOptions = {
            filter: function(element) {
                return element.className ? element.className.indexOf('ol-control') === -1 : true;
            }
        };
    
        document.getElementById('export-png').addEventListener('click', function() {
            map.once('rendercomplete', function() {
                toPng(map.getTargetElement(), exportOptions)
                    .then(function(dataURL) {
                        var link = document.getElementById('image-download');
                        link.href = dataURL;
                        link.click();
                    });
            });
            map.renderSync();
        });
    
        var image = new CircleStyle({
            radius: 5,
            fill: null,
            stroke: new Stroke({ color: 'red', width: 1 })
        });
    
        var styles = {
            'Point': new Style({
                image: image
            }),
            'LineString': new Style({
                stroke: new Stroke({
                    color: 'green',
                    width: 1
                })
            }),
            'MultiLineString': new Style({
                stroke: new Stroke({
                    color: 'green',
                    width: 1
                })
            }),
            'MultiPoint': new Style({
                image: image
            }),
            'MultiPolygon': new Style({
                stroke: new Stroke({
                    color: 'yellow',
                    width: 1
                }),
                fill: new Fill({
                    color: 'rgba(255, 255, 0, 0.1)'
                })
            }),
            'Polygon': new Style({
                stroke: new Stroke({
                    color: 'blue',
                    lineDash: [4],
                    width: 3
                }),
                fill: new Fill({
                    color: 'rgba(0, 0, 255, 0.1)'
                })
            }),
            'GeometryCollection': new Style({
                stroke: new Stroke({
                    color: 'magenta',
                    width: 2
                }),
                fill: new Fill({
                    color: 'magenta'
                }),
                image: new CircleStyle({
                    radius: 10,
                    fill: null,
                    stroke: new Stroke({
                        color: 'magenta'
                    })
                })
            }),
            'Circle': new Style({
                stroke: new Stroke({
                    color: 'red',
                    width: 2
                }),
                fill: new Fill({
                    color: 'rgba(255,0,0,0.2)'
                })
            })
        };
    
        var styleFunction = function(feature) {
            return styles[feature.getGeometry().getType()];
        };
    
    
    
        var vectorLayer = new VectorLayer({
            source: new VectorSource({
                format: new GeoJSON(),
                url: 'v1/track?journey=#####'
            }),
            style: styleFunction
        });
    
    
    
        var map = new Map({
            layers: [
                new TileLayer({
                    source: new OSM()
                }),
                vectorLayer
            ],
            target: 'map',
            view: new View({
                center: [0, 0],
                zoom: 2
            })
        });
    
    });