Turbo and Stimulus Feedback

Hi,

I’m new to Hotwire and I’m trying to find the most rails-turbo-way to do activate javascript code with information of a model element freshly created on the database with turbo.

I have a page with an open layer map where I want people to be able to click to create a feature (a “sensor” in my application), fill a form and after it’s validated the feature created is on the map if created. I also have a list of the sensors created.

The part that put the feature on the map has to be Stimulus since it’s using only JS and no HTML.

I’m struggling for the end of this action : how to update the js map when the database element is created.

The first option I found is to use a broadcast with a custom action adding this to the Sensor model :

 after_create -> {
   content = turbo_stream_action_tag(:sensor_created, sensor_id: self.id, geometry_type: "Point", geometry_loc_x: self.x_in_featured_image, geometry_loc_y: self.y_in_featured_image)
   ActionCable.server.broadcast(stream_name_from(:sensors), content)
  }

And after I can get this event in my js code by overriding the action in StreamActions :

  StreamActions.sensor_created = function() {
    const geometry_loc_x = this.getAttribute("geometry_loc_x")
    const geometry_loc_y = this.getAttribute("geometry_loc_y")
    const sensor_id = this.getAttribute("sensor_id")
  // do my stuff with the open layers map

  }

This works but I’m not a fan of this solution because :

  • I’m using websocket for something that doesn’t really need it
  • I’m having a rendering logic in the model
  • This broadcast is specific to JS and I’ll need another thing to update the HTML of the page

Is there a better way to do this kind of simple “feedback”? I was also thinking of launching the creation of the sensor from JS to get the HTML code to know if I keep or not the feature but I’m not sure it’s better…

Another very nice option I found but that I couldn’t make work is to directly work with the built in append action, in the model I create an append broadcast :

 after_create -> {
    broadcast_append_to :sensors
}

In the js I intercept this append :

    StreamActions.append = function(e) {
       console.log("from append")
       // do the openlayers suff
       originalAppend.bind(this).call()
     }

The problem here is that this is a dom element and to get back sensor informations I need I’ll have to get attributes from the dom elements which doesn’t feel like a nice Stimulus way…

Any better suggestions?

Maybe you don’t need the Hotwired here? Since you wrote:

The part that put the feature on the map has to be Stimulus since it’s using only JS and no HTML.

Just response in action with js format. And accordingly make request to that action with any tool like GitHub - rails/request.js

  • I’m using websocket for something that doesn’t really need it
    I would consider websocket in case where I would have plans about updating this info on another opened pages or for other users.
  • I’m having a rendering logic in the model
    It’s totally fine.