Problem loading javascript with turbo (rails 8)

I have previously dabbled in rails a bit to develop a GUI for a database with very basic user authentication and various ways to navigate the data and display it.

Part of this is an external javascript package called phylocanvas.gl (https://www.phylocanvas.gl/) - which allows me to display phylogenetic trees (biological relationships).

The issue I am having is that the darn script only loads after a manual page refresh - which seems to be related to turbo. Now, being the rails noob that I am, I am very stuck. Any suggestions on how to modify the script to load when I open the page without manual reloading?

Snippet from the erb template:

<script>
  
      const tree = new phylocanvas.PhylocanvasGL(
        document.querySelector("#phylocanvas"),
          {
          size: { width: 1600, height: 800 },
          source: `<%= @xref_analysis_partition.cluster_analysis.tree %>`,
          type: phylocanvas.TreeTypes.Radial,
          interactive: true,
          showLabels: true,
          showBranchLengths: true,
          showLeafLabels: true,
          fontSize: 10,
          branchLabelsFontSize: 10,
          styles: {
            <% @profiles.each do |cp| %>
              <% if @sample_colors.has_key?(cp.name) %>
                <% colour = @sample_colors[cp.name] %>
              <% else %>
                <% colour = "997aae" %>
              <% end %>
              "<%= cp.name %>": { fillColour: "#<%= colour %>" , label: "<%= cp.name %>" },
            <% end %> 
          },
        }
      );

      </script>

Turbo provides a hook event for this purpose. Although I don’t see it in the code you posted, here’s no way to tell from your example if the target is above the script tag in source order or not. The way it looks now, the script would have to be below the target in order to guarantee that it would find the element. Unless Turbo also replaces the script tag along with the target during the page navigation, there’s no guarantee that this is true.

I would expect to see a document.addEventListener(‘dom:loaded’, function(evt) { …something here… })to kick this all off without worrying about the target appearing first.

If you replace dom:loaded with turbo:load, you will get a Turbo-aware event that fires both when the dom is loaded initially, and also when a Turbo navigation replaces the page content.

If for some reason this is not how your page works, then the other thing to look out for is duplicate element IDs. As with any JavaScript browser interaction, the underlying dom must be valid to work predictably.

Walter

Hi, and thanks for the reply. Yes, I guess my example misses some information.

This is the actual erb:

https://github.com/marchoeppner/epitracker/blob/dev/app/views/xref_analysis_partitions/show.html.erb

That must be a private project: the link 404s for me.

Ah… well, then:

Due to how Turbo Drive works, I’d recommend not using script tags like that but instead wrapping this library in a stimulus controller!

1 Like