Search code examples
javascripthtmlhtmx

Resume polling after 286


Making a small game with HTMX and Go. I'm having HTMX poll the server and updating the state of the game every 1 second or on user input

<div class="game" hx-post="/tick" hx-trigger="every 1s, keydown[ (some keys here) ] from:body">
    {{ block "state" . }}
    <!-- state -->
    {{ end }}
</div>

When the game ends, I send 286 status code to stop the polling of "every" trigger, as mentioned here.

The user is given the option to restart the game, how can I resume the polling?

Note that moving the div inside the state block is not an option, because then user inputs reset the 1 second timer.

Is there another status code that can be sent? or even some custom JS to restart the polling?


Solution

  • HTMX way

    Restart button could reload the whole <div class="game"..>. For example, I've defined /new-game endpoint returning the game field:

    <div class="game" hx-post="/tick" hx-trigger="every 1s, keydown[ (some keys here) ] from:body">
    </div>
    

    and the restart button looks like:

    <button hx-get="/new-game" hx-trigger="click" hx-target=".game" hx-swap="outerHTML">Restart</button>
    

    Since we're using hx-swap="outerHTML" it will replace the whole element and HTMX will start handling it from scratch.

    Pure JavaScript

    You also have an option to do the same with pure JavaScript by recreating div.game and calling htmx.process('.game') to set it up.

    Just calling htmx.process on the already processed element doesn't work. So you have to create a new one, as an easy option you could leverage node.cloneNode() API.

    function restartGame() {
        const game = htmx.find('.game');
        const clone = game.cloneNode();
    
        game.parentNode.insertBefore(clone, game);
        htmx.remove(game);
        htmx.process('.game');
    }
    
    <button onclick="restartGame()">Restart</button>