I'm trying to update Liveview with Javascript after a Javascript event is fired.
Liveview must show a <div>
element with some values sent from Javascript.
My question is: how should I pass those values from Javascript to Liveview?
I might also need value sent by Liveview in Javascript. Again: how should I pass those values from Liveview to Javascript?
There is a Livesocket created in Javascript for liveview to work but I see no way to get or set assign values from there. The only way to pass values from/to Liveview seem to be via the DOM at some point. For example:
<div id="lv-data" phx-hook="JavascriptHook"></div>
let hooks = {};
hooks.JavascriptHook = {
mounted(){
this.el.addEventListener("jsEvent", (e) =>
this.pushEvent("jsEventToPhx", e.data, (reply, ref) =>
console.log("not sure what to do here")));
this.handleEvent("phxEventToJS", (payload) => console.log("data received: " + payload));
}
}
This feel weird to have to use the DOM with a dummy <div>
at all for pure data exchange...
I'm trying to update Liveview with Javascript after a Javascript event is fired.
Liveview must show a <div>
element with some values sent from Javascript.
My question is: how should I pass those values from Javascript to Liveview?
I might also need value sent by Liveview in Javascript. Again: how should I pass those values from Liveview to Javascript?
There is a Livesocket created in Javascript for liveview to work but I see no way to get or set assign values from there. The only way to pass values from/to Liveview seem to be via the DOM at some point. For example:
<div id="lv-data" phx-hook="JavascriptHook"></div>
let hooks = {};
hooks.JavascriptHook = {
mounted(){
this.el.addEventListener("jsEvent", (e) =>
this.pushEvent("jsEventToPhx", e.data, (reply, ref) =>
console.log("not sure what to do here")));
this.handleEvent("phxEventToJS", (payload) => console.log("data received: " + payload));
}
}
This feel weird to have to use the DOM with a dummy <div>
at all for pure data exchange...
1 Answer
Reset to default 6Is your LiveView
module implemented to handle the jsEventToPhx
event you're sending from the front-end? You must have a parent LiveView
or LiveViewComponent
which implements the handle_event/3
callback for the this message. See:
https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#c:handle_event/3
For example (in your LiveView module):
def handle_event("jsEventToPhx", params, socket) do
# Here the `params` variable is what you are sending form the
# client-side, so it will be `%{foo: "bar"}` if you
# follow the next example.
{:reply, %{hello: "world"}, socket}
end
Then in your Hook, all you need is to use this.pushEvent
:
let hooks = {};
hooks.JavascriptHook = {
mounted(){
this.pushEvent("jsEventToPhx", {foo: "bar"}, (reply, ref) =>
// this will print `{hello: "world"}`
console.log(reply)
);
}
}
This is the approach when you want to send data to LiveView and optionally receive the response immediately.
If you want to send something from LiveView
to the client, then the process is slightly different. From LiveView you use push_event
when returning a socket from any handle_event
callback, for example:
{:noreply, push_event(socket, "phxEventToJS", %{abc: "xyz"})}
And in your Hook, you subscribe to events:
mounted(){
this.pushEvent("jsEventToPhx", {foo: "bar"}, (reply, ref) =>
// this will print `{hello: "world"}`
console.log(reply);
}
this.handleEvent("phxEventToJS", (payload) => {
// this will print `{abc: "xyz"}`
console.log(payload);
}
}
It may be useful to check the client-server munication section here.