Search code examples
restxmlhttprequesthtmx

Can I get hx-trigger to respond to an HX-Trigger header in a non-htmx request?


I am struggling to get hx-trigger to respond to an HX-Trigger header in a response to a PUT request I am not sending from an htmx element. I have the following request (somewhat simplified in pug):

form
    input(
        id="rfile"
        name="rfile"
        type="file"
    )
    button(type="button" onclick="saveFile()") Upload
    script(type="text/javascript").
        async function saveFile() {
            var fileInput = document.getElementById('rfile').files[0];

            if (fileInput) {
                var reader = new FileReader();
                reader.onload = function() {
                    var xhr = new XMLHttpRequest();
                    xhr.open('PUT', '/dataset/', true);
                    xhr.setRequestHeader('Content-Type', 'application/x-zip-compressed'); // Set the appropriate Content-Type
                    xhr.send(atob(reader.result.split(',')[1])); // Send the ArrayBuffer as the request body
                };
                reader.readAsDataURL(fileInput); // Read the file as an ArrayBuffer
            } else {
                console.log('Please select a file.');
            }
        }

The above sends a request to the web server that includes the raw file content in the body. I unfortunately cannot use multipart/form-data to submit the request because the body has to be comprised entirely of the raw file.

The above request is sent successfully. The response to the request looks like the following:

HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
HX-Trigger: refreshDatasets
...

I include the HX-Trigger: refreshDatasets header in the hopes of triggering the following, elsewhere in the DOM:

div(id="datasetList" hx-get="/datasets" hx-trigger="load, refreshDatasets from:body")

However, when the response comes back from the server, nothing happens. I know that this element will trigger in response to the HX-Trigger header because it triggers in a response to a request created and sent by an HTMx element. However when the response is returned for my manually created XHR request above, nothing happens.

Is there a way I can have this element triggered by a response to my manually created XHR request? or, perhaps, is there a different way I should be sending my initial request such that it is capable of triggering the GET request from datasetList?

Any help is appreciated!


Solution

  • I don't think it's possible when using raw xhr. You need to use htmx.ajax api to allow htmx to process the response headers for you.

    You can accomplish similar thing, without much changes, by handling xhr.onloadend callback:

    var xhr = new XMLHttpRequest();
    
    xhr.onloadend = () => {
        // Request finished. Do processing here.
        htmx.trigger('body', 'refreshDatasets')
    };