How to turn Elixir into HTML and JS?

Hello! As part of working on a small Elixir project, I’m trying to turn some of the data structures into HMTL and JS and looking for some pointers on how to do so.

Let’s say I have a data structure like so and want to draw it on an HTML canvas.
%Node{ x: 10, y: 10, size: 10 }

Rendering the EEx to an HTML string is simple enough, but how could I generate dynamic JS that would, say, draw n number of Nodes to the HTML canvas?

I suppose I could add a <script> tag in the EEx, but that doesn’t feel very robust - does anyone know how Phoenix handles bundling dynamic JS?

That does not answer your question directly but I feel like you want to use Phoenix Channels and coordinate using websockets. It’s ridiculously easy to use websockets on a phoenix app, everything just works ™️ and you can do bi directional communication with your server.

But in case you just want a once-and-done sort of “render an elixir map as JS” I’d just use some way of converting my map into JSON (probably using Jason) and rendering inside a script tag like you mentioned.

You can use JS Hooks with LiveView. Just talk to your front end through events!


Communication with the hook from the server can be done by reading data attributes on the hook element or by using Phoenix.LiveView.push_event/3 on the server and handleEvent on the client.

However, the data attribute approach is not a good approach if you need to frequently push data to the client. To push out-of-band events to the client, for example to render charting points, one could do:

# Register Hook
<div id="canvas" phx-hook="Canvas">

# Send down your Data Structure
{:noreply, push_event(socket, "data", %{data: new_data})}

On client:

Hooks.Canvas = {
    this.handleEvent("data", ({data}) => {
        // Draw Data Structures onto canvas.

See: Client Server Communications

P.S. I just assumed you are also using Phoenix Framework & LiveView.

1 Like

Maybe use, live-view and and js hooks.

You can use Phoenix channels or Phoenix LiveView with Surface components. It’s makings LiveView development more convenient