Just posting this for future me and other travelers.
In JS I was used to trying to detect the "load"
event as a trigger to do stuff when the page has loaded but that has already fired by the time you would set up a listener so you can just push the event directly inside the mount
function (the JS one).
In app.js
const Hooks = {
ScreenSize: {
mounted() {
// If you want to listen on resize and push the same event
window.addEventListener("resize", (e) => {
this.pushEvent("page-size", {
screenWidth: window.innerWidth,
screenHeight: window.innerHeight,
});
});
this.pushEvent("page-size", {
screenWidth: window.innerWidth,
screenHeight: window.innerHeight,
});
},
},
};
// Amended boilerplate...
let csrfToken = document
.querySelector("meta[name='csrf-token']")
.getAttribute("content");
let liveSocket = new LiveSocket("/live", Socket, {
params: { _csrf_token: csrfToken },
hooks: Hooks,
});
Somewhere on the page tie in the event to the named hook. This is in a heex
file or a render
function. It doesn’t have to be a div
.
<div phx-hook="ScreenSize" id="screen-size">
Then in your :live_view
module put in a function to handle the event.
def handle_event(
"page-size",
%{"screenWidth" => screen_width, "screenHeight" => screen_height},
socket
) do
# Whatever your logic is ....
{:noreply, socket}
end
As a side note (not part of the solution). if you really need to listen for a ‘done loading’ event, "phx:page-loading-stop"
might work better. I can imagine this potentially being useful on the JS side, not so much the Phoenix side.
I hope this helps!