Call javascript function on the client from the server

Hi,

I have a LiveView, and I want to add a SVG item and some associated javascript functions.
The SVG shall show an XY plot, and the functions are for defining the axes and adding new data points.

New data will come in from a measurement device (e.g., a multimeter) in an erlang application.
My plan is to transfer those data with some kind of push from the server via the LiveView WebSocket to the client and execute the javascript function there.

It has been a while since I last programmed in phoenix, and I would appreciate some pointers.

  • How can i push the data to the client and use them as parameters in a javascript function call.
  • Or is there maybe a simpler way to update a SVG element from the server side?

Thanks in advance!

Take a look at JavaScript interoperability — Phoenix LiveView v0.20.17

Check out ContEx Charts!

1 Like

Sorry for the delay.

@codeanpeace Thank you very much for this link, I didn’t know about this library.
It also contains links to other works, which look very promising.

@LostKobrakai I should have mentioned that I already had a look into the JS interop documentation. For me, it is not very helpful. It seems to be mostly about how to interact with the DOM and not how to call a JS function which is defined in a on the client. OR maybe I just don’t see it…

You can’t randomly call some JS on the client – but also that wouldn’t be useful in the first place. LV does add and remove html from your page, so your SVG you want to target might be added/removed/… from the DOM by LV at any time. It might not even be there at the time you would call the JS function.

Hence you need to integrate with the lifecycle of the SVG on the page, which is done through hooks. They allow you to call the JS function you want to call not at a random time, but actually once the SVG is rendered within the page, as well as allowing for additional concerns like cleanup once the svg is removed from the page. E.g. if you navigate away using live navigation the svg would be removed from the page and you don’t want to leak memory to the new page.

A little late, but I ran into something similar a few days back while setting up Sentry: I wanted to set the user details after someone logged in. That can only be done in the client-side JavaScript with the Sentry browser library.

The JavaScript Interop doc was helpful once I wrapped my head around just using the events: e.g. I was adding some DOM elements that had data for the user details and could listen to an event in my JavaScript (imported into app.js).

Because I had existing DOM elements to trigger on/off of, I went that route. Looks like you can push an event from the server as well. If your code is really about handling that new SVG, though, it seems better to listen for events on the DOM element. JS.dispatch may also be helpful.

Thanks for this!

I also needed some wrapping. In the end I used an event listener for my implementation.
In the end, I do modify the DOM, but I need to do it via a JS function on the client, which
pushes the data into the SVG.

(It is also in part done by my son, who worked for me as a summer intern :slight_smile: )

I tried to put the essence into a small project, which I uploaded here.

Hopefully it is of interest for somebody.

1 Like

Nice! Congrats to your son on the internship.

And this definitely looks similar to what I did. Thanks for creating a sample folks can follow!

The approach is to have a hook listening for an event from the server. The server pushes the event with relevant data. The hook or js is listening for that event. From there do what you like.