ndarilek
Arbitrary JavaScript on LiveView update
I’m about to use LiveView for the first time. I think I get how it works when updating the DOM, hiding/changing controls, etc. but is it possible to run arbitrary JavaScript when a new message is received?
We’re building a document conversion service. When the page loads, I set the title to “Loading…” Eventually, our converter returns an actual document title, at which point I want to run document.title = title or something equivalent to include the actual document’s title in the page. Titles are generated in the layout’s view, so aren’t in the LiveView itself.
Maybe there’s a better way to set the title, but is it possible to run other client-side code when certain messages are received? We have some complex client-side state that doesn’t always translate to DOM updates–libraries that need to be called on the client whenever new content is received, for instance. I think hooks may help here, but I’m not clear how, nor am I clear how to use specific hooks on specific pages rather than globally.
Thanks.
Most Liked
snewcomer
Currently, hooks only respond to mounted (when element under view is added and LV has finished mounting) or updated (when the DOM has been updated). It seems like you have neither and need state available client side.
One thing I would like to explore is a meta tags solution for LV, especially as it relates to live_link. Effectively, we need to propagate changes server side to the meta tags client side and I don’t think we have a solution yet.
mindok
Hi @ndarilek,
Conceptually you are spot on. Package your data into a DOM element that has a JS hook attached, and use it in the hook. Your version may not work as the hook has to be associated with an element that has a socket assign that is changing in order for it to fire, and also note that the hook has direct access to the element it is associated with so you don’t need to look it up with a selector. I’d personally code it along the lines of:
leex
<div id="my-id" data-title="<%= @document.title %>" phx-hook="DocumentShow"></div>
and in the JS:
Hooks.DocumentShow = {
mounted() {
this.updateTitle();
},
updated() {
this.updateTitle();
},
updateTitle() {
var title = this.el.dataset.title; // You have access to the element within the hook
document.title = title;
}
};







