Want to join a channel only on certain pages, do it within phx-hook?

I want to join a private channel only on a specific liveview page.

I’m using the phx-hook to run the channel.join when that specific area is mounted. But I needed a reference to the socket.

So I changed the generated user_socket.js a little bit to save the socket on the window object.

import { Socket } from "phoenix"
window.socket = new Socket("/socket", { params: { token: window.userToken } })

Then in my hook chat.js file:

export const Chat = {
  mounted() {
    let someId = document.getElementById('someId').dataset.someId

    const channel = window.socket.channel(`conversation:${someId}`, {});

      .receive("ok", resp => { console.log("Joined successfully", resp) })
      .receive("error", resp => { console.log("Unable to join", resp) })

    channel.on('shout', (payload) => {

My question:

Is this the right way to structure this? Are there any negatives to saving the socket to window.socket?

Well, no, you’re creating a global variable in the JavaScript runtime. It can work like that but you’re polluting the global namespace this way.

I think what would be a better solution is to use import/export functionality of JavaScript.

In the user_socket.js you either export the socket variable itself, or you export a function that would return that variable when called.

In the chat.js you then need to import either that socket or the function.

Personally I’ld go with a function but I think both solutions would work.