ArrowOD
ArrowOD

Reputation: 11

Trouble with Server Side Events in HTMX and Go

I am having trouble getting HTMX to swap out a div after receiving SSE. In Chrome I can clearly see the event was actually received. But HTMX doesn't seem to respond to it. What am I missing?

The tab on the left should've updated to show the newly joined player

I've tried enabling the HTMX logs, but only receive the following log upon receiving the SST:

[email protected]:1 htmx:sseOpen <div hx-ext=​"sse" sse-connect=​"/​events/​2275600710884066084" sse-swap=​"PlayerJoined" class>​<span>​<button onclick=​"copyToClipBoard()​" class=​"text-xl font-bold">​copy session link​</button>​<p>​waiting for second player​</p>​<p>​player 0: a​</p>​<h2>​session code: 2275600710884066084​</h2>​</span>​</div>​ {source: EventSource, elt: div}

The necessary headers are set and the received message, to me, looks as expected:

event: "PlayerJoined"
data: "<p> Hello World! </p>"

The connections stays open without an issue and on the server side I can see the events are sent as expected.

I've also tried putting the hx-ext="sse" tag further up the component tree to no avail.

For more information there I've already created a thread on the HTMX reddit: https://www.reddit.com/r/htmx/comments/1hfi4gx/trouble_with_server_side_events_and_go/

And for more context of the code this is the GH repo (if anyone wants to drill further into this): https://github.com/F-bh/GHQ

What am I missing?

The component that should update:

  <div hx-ext="sse" sse-connect={ fmt.Sprintf("/events/%v", sessionId) } sse-swap="PlayerJoined">
    <span>
      if len(players) < 2 {
        <button onClick="copyToClipBoard()" class="text-xl font-bold">copy session link</button>
        <p>waiting for second player</p>
      }
      for x, player := range players {
        <p>player { fmt.Sprintf("%v",x) }: { player } </p>
      }
      <h2>
        session code: { sessionId }
      </h2>
    </span>
  </div>  <div hx-ext="sse" sse-connect={ fmt.Sprintf("/events/%v", sessionId) } sse-swap="PlayerJoined">
    <span>
      if len(players) < 2 {
        <button onClick="copyToClipBoard()" class="text-xl font-bold">copy session link</button>
        <p>waiting for second player</p>
      }
      for x, player := range players {
        <p>player { fmt.Sprintf("%v",x) }: { player } </p>
      }
      <h2>
        session code: { sessionId }
      </h2>
    </span>
  </div>

Upvotes: 1

Views: 125

Answers (1)

ArrowOD
ArrowOD

Reputation: 11

The fix was changing one line of code.

from:

fmt.Fprintf(w, "event: \"%v\"\ndata: \"%v\"\n\n", e.name, e.data)

to:

fmt.Fprintf(w, "event: %s\ndata: %s\n\n", e.name, e.data)

Upvotes: 0

Related Questions