Mounting a LiveView from Javascript

I have managed to send a chat request to the javascript code of my client. What I would like to do is to mount a LiveView on receiving that notification. My code so far:

import { Socket } from ‘phoenix’;
import $ from ‘jquery’;

CSRF_TOKEN = $(“meta[name=‘x-user-token’]”).attr(“content”)
const socketo = new Socket(‘/socket’, { params: { token: CSRF_TOKEN } });
socketo.connect();

let channel = socketo.channel(“room:livechatrequests”, {})
channel.join()
.receive(“ok”, resp => { console.log(“Joined successfully”, resp) })
.receive(“error”, resp => { console.log(“Unable to join”, resp) })
channel.on(“message”, (payload) => {
console.log(“Received request:”, payload);
async function fetchAsync (url) {
let response = await fetch(url);
console.log(response);
return response;
}
fetchAsync(“/live_chat”)
.then(response => console.log(response.text()))
.catch(error => {
console.error(“Error mounting LiveView:”, error);
});
});

The response code is 200, no errors are thrown, and the LiveView is mounted, but the template does not appear. Can anyone say why this is? Thanks.

You cannot easily mount a LV through custom JS. Consider navigating to a page, which renders that liveview anyways or prematurely add LV to the client page, which reacts to the notification on the server side.

The fetchAsync(“/live_chat”) does just that. This is the relevant line in the router:

live “/live_chat”, LiveChatModalLive, :create.

As I said, the mount succeeds, but the template is not displayed.

No it doesn’t. That’s not the browser navigating to /live_chat. That’s JS doing a http request for /live_chat. This will give you the html returned by the static render, but nothing else will happen. Nothing of LVs client side code will be executed like that.

My goal is to have the client listen on a channel for a notification and then mount a LiveView on receiving the notification. So there is no way to do this?

I wouldn’t say there’s no way, but there are at least no intended ones. That’s not how LV is meant to be used. Instead have a LV (whole page or nested within the page), which listens to notifications and renders them when receiving them. No need to involve the client or separate channels.