Demos of OpenLayers and Leaflet Using Rails 7 With HotWire Stimulus
I put this together to gather what I'm learning works for me with Rails 7 (7.0.4) and integrating OpenLayers and Leaflet. I am trying to upgrade another app and kept running into problems. An old app made by a rank amateur (me). Tried Import Maps with various combinations. Kept getting thrown because Bootstrap forces esbuild (may be workaround, but that is the default). And it seemed plugins to Leaflet or OpenLayers didn't work well or required additional steps. Unfortunately I started to update the app as Rails 7 was coming out and Stimulus was evolving which was too early.
Settling on esbuild (node_modules and yarn, etc.). See the ReadMe at Gitbub for build details and code. Postgres database setup, but no databases are used in this app, but I use Postgres so wanted this app to mimic that.
Why Stimulus? I'm not using sprinkles of JavaScript; I'm using large chunks. But I felt Stimulus isolates the JavaScript to one div (controller and target). With Webpack(er), my JavaScript would step on other parts of the page or other pages. Of course, someone who knew what they were doing could avoid this. Stimulus may be more verbose, but controller and targets are clearly identified (with the caveat below about targets).
Currently (Jan. 2023), Rails Guides, Working with JavaScript in Rails does not mention Stimulus and barely touches on esbuild.
OpenLayers seems to be changing the canonical way to import, for example,
import {Group as LayerGroup, Tile as TileLayer, Image as ImageLayer} from 'ol/layer.js';
typical now. '.js' and 'Something as Something'.One gotcha is that Stimulus has a 'target' and so does OpenLayers and Leaflet. I haven't developed a consistent naming convention which can make debugging difficult. This gets more complicated if two maps are on the same web page. For that reason I try not to use the generic `map` for the OpenLayers/Leaflet 'target' (the 'id=map'. I also thought I had issues with the Stimulus 'targets' getting confused with more than one map per page. Maybe use the same name for both targets or is the Stimulus `targets` being used at least as long as only using the controller on one page.?
Another gotcha is with copy and pasting the html.erb. Stimulus controller name is repeated and easy to misread with all the hyphens, but longer, more descriptive controller names are useful. For example:
<div id="mapolg"
data-controller="ol-layer-group"
data-ol-layer-group-target="lgmap"
style="height:400px">
</div>
Something else I don't understand is that Leaflet code can be plugged into Stimulus without change as long as
is added to `application.bootstrap.scss`. (And why is the default not `application.scss` with `bootstrap` imported? ) With OpenLayers referenced to `map` need to be changed to `this.map`. No doubt those with a better understanding of Rails and JavaScript will know why this is.
import L from "leaflet"
is included in the Stimulus controller and@import 'leaflet/dist/leaflet'
@import 'ol-layerswitcher/dist/ol-layerswitcher';
is added to `application.bootstrap.scss`. (And why is the default not `application.scss` with `bootstrap` imported? ) With OpenLayers referenced to `map` need to be changed to `this.map`. No doubt those with a better understanding of Rails and JavaScript will know why this is.
I just discovered Stimulus debugging which should prove useful. But this is for an older stimulus?
The left sidebar lists the demos I put together to help me sort this out (The list below may not be up to date). I tried to do this in my existing apps but ran into conflicts. Most of the examples come from elsewhere and are linked in the headings. Of course, other pieces from Stackoverflow and several early blogs on Stimulus. (The naming of some of the controllers should be refactored since I had used what at the time was a good name, but now not so much.)
OpenLayers With More Complex Layer Group
ArcGIS REST Feature Service. Has a VectorLayer which didn't work in the above example, but works here. not in nav system on the other pages
Drag-and-Drop Image Vector
Snippet like Crores app. Can't load image from Amazon
Leaflet With Timeline From Skeate. Not working.
Leaflet With Timeline Using?. A more complex version of the previous, so I put together that one to sort out what was going on. Since that didn't work, not pursuing this either.
The two apps I'm working on: Croatian Operated Restaurants in Early Los Angeles and Historical Street Names in Los Angeles. I hope to get back to these now that I'm sorting out Stimulus and fly.io (moved from Heroku).
Stimulus and OpenLayers is coming together for me now that I'm integrating what I learned here into the two projects above. One difference is they use JavaScript Bundling for Rails (jsbundling-rails) and webpack which is a bit different than this app which is JavaScript Bundling for Rails and esbuild. I think for me the differences are minor but can create confusion when something doesn't work right. I think esbuild is enough for my application, but since it was webpack(er) already, I stopped.