Home > database >  Rails 7 importmap Stimulus controller configuration for OpenLayers?
Rails 7 importmap Stimulus controller configuration for OpenLayers?

Time:10-30

Rails 7 importmap leaflet-css images path fix? showed how to get leaflet working in a Stimulus controller.

import { Controller } from "@hotwired/stimulus";
import "leaflet-css";

export default class extends Controller {
static targets = [ "trial" ]

connect(){
    import("leaflet").then( L => {
        this.map = L.map(this.trialTarget).setView([ 51.472814, 7.321673 ], 14);
        var base_map = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> | <a href="https://www.swmmgo.com">SwmmGo</a>',
            transparency: true,
            opacity: 0.5
        }).addTo(this.map);

Can't figure out how to do this with OpenLayers. import("leaflet").then( L => { mapping is probably the key, but I don't understand what this is doing.

Beginning of controller:

import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
   static targets = [ "map" ]

    connect(){
      import("openlayers").then( ol => {
      import GeoJSON from 'ol/format/GeoJSON';
      etc.

Error is: controller: street (controllers/street_controller) SyntaxError: Unexpected identifier 'GeoJSON'

# config/importmaps.rb
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true

pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true # Rail7 default also
pin_all_from "app/javascript/controllers", under: "controllers"

pin "jquery", to: "https://ga.jspm.io/npm:[email protected]/dist/jquery.js", preload: true
pin "popper", to: 'popper.js', preload: true
pin "bootstrap", to: 'bootstrap.min.js', preload: true

pin "leaflet", to:          "https://ga.jspm.io/npm:[email protected]/dist/leaflet-src.js", preload: true
pin "leaflet-css", to:      "https://ga.jspm.io/npm:[email protected]/dist/leaflet.css.min.js", preload: true
pin "leaflet.timeline", to: "https://ga.jspm.io/npm:[email protected]/dist/index.js", preload: true

pin "openlayers", to: "https://ga.jspm.io/npm:[email protected]/dist/ol.js"

CodePudding user response:

This is a partial answer in that I changed to esbuild since it aligned better with node_modules and I could leverage some suggestions I saw for frameworks other than Rails. I made a simple controller to sort out the problems.

// app/javascript/controllers/ol_map_test_controller.js
import { Controller } from "@hotwired/stimulus"
import ol from 'openlayers/dist/ol.js' 
// import Map from 'ol/Map' // does not work. Errors in compilation

export default class extends Controller {
  static targets = [ "test" ] // is for Stimulus
  connect() {
    this.map = new ol.Map({
      // this.map = new Map({
      target: 'map', // #map defined separately from Stimulus target
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM()
        })
      ],
      view: new ol.View({
        center: [0, 0],
        zoom: 2
      })
    });
  }
}

and the HTML

<div id="map" data-controller="ol-map-test" data-ol-map-test-target="test" style="height:200px"></div>

Two things had to be done. Abandon defining Map from 'ol/Map' and associated wizardry of OpenLayers, i.e., not 'new Map'. One hopes that will get sorted out.

Secondly the div id has to be explicitly defined in HTML since Stimulus doesn't add that. The two targets could both be named map but for my sanity I named them differently.

Unfortunately this doesn't solve my problem as an OpenLayers module I need has the modern wizardry and doesn't compile the js.

I may see if this works with importmaps, but wanted to post this while I remembered what I had done.

One advantage to Stimulus is that one can easily experiment with other sample controllers with only one line of HTML.

  • Related