Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static template that doesn't parse the response #3082

Open
thenewguy opened this issue Dec 17, 2024 · 7 comments
Open

Static template that doesn't parse the response #3082

thenewguy opened this issue Dec 17, 2024 · 7 comments

Comments

@thenewguy
Copy link

thenewguy commented Dec 17, 2024

With a current use case, the response from the POST isn't important - the side effect is handled by path-deps and that handles the re-render. It is only important to let the user know there if was an error.

As such, it would be helpful to be able to provide a static template block that does not parse the response.

For example:

<div id="hidden" style="display:none"></div>
<div id="unrecoverable-error"></div>
<template id="unrecoverable-error-template">Some static message explaining that an unknown error was encountered.</template>
<form 
	hx-patch="/endpoint"
	hx-target="#hidden"
	hx-target-error="#unhandled-error"
	handlebars-template="unhandled-error-template"
	hx-on-htmx-before-request="$('#unhandled-error').empty()"
>
	<input type="hidden" name="some-trigger-key" value="1">
	<button type="submit">Submit</button>
</form>

Using the available template engines causes a Parsing error in Javascript when JSON isn't returned by a 500 error and htmx falls back to inserting the response into "#unhandled-error" instead of the static message.

Being able to force the static message to display would be very beneficial.

@Telroshan
Copy link
Collaborator

As you linked the v1 docs, I suppose you're using htmx v1 and not v2 here ?
Looking at the code, I suppose you're using the response targets extension too along client-side-templates?

@scrhartley
Copy link
Contributor

Is the mismatch between ids relevant (unrecoverable vs. unhandled)?
<template id="unrecoverable-error-template"> vs. handlebars-template="unhandled-error-template"
and
<div id="unrecoverable-error"></div> vs hx-target-error="#unhandled-error" and $('#unhandled-error').empty()

@thenewguy
Copy link
Author

Is the mismatch between ids relevant (unrecoverable vs. unhandled)? <template id="unrecoverable-error-template"> vs. handlebars-template="unhandled-error-template" and <div id="unrecoverable-error"></div> vs hx-target-error="#unhandled-error" and $('#unhandled-error').empty()

No - sorry that is a copy paste error from reformatting the real markup to be easier to read for the example.

What happens here is the server returns a response with an error status code. HTMX produces a Json Decoding error because the error response isn't formatted with JSON. And then HTMX inserts the server response instead of the static message from the template.

@scrhartley
Copy link
Contributor

scrhartley commented Dec 18, 2024

htmx:beforeSwap has currently undocumented isError and serverResponse properties.

Perhaps you could add something like:
hx-on-htmx-before-swap="if (event.detail.isError) event.detail.serverResponse = '{}'"

@thenewguy
Copy link
Author

htmx:beforeSwap has currently undocumented isError and serverResponse properties.

Perhaps you could add something like: hx-on-htmx-before-swap="if (event.detail.isError) event.detail.serverResponse = '{}'"

Awesome! Thanks!

@thenewguy
Copy link
Author

htmx:beforeSwap has currently undocumented isError and serverResponse properties.

Perhaps you could add something like: hx-on-htmx-before-swap="if (event.detail.isError) event.detail.serverResponse = '{}'"

I tried this:

<form 
	hx-patch="/placeholder/url"
	hx-target="#devnull"
	hx-target-error="#unhandled-error"
	handlebars-template="unhandled-error-template"
	hx-on-htmx-before-request="$('#unhandled-error').empty()"
	hx-on-htmx-before-swap="if (event.detail.isError) event.detail.serverResponse = '{}'"
>

It did not solve the issue. Note that it seems to work without hx-on-htmx-before-swap="if (event.detail.isError) event.detail.serverResponse = '{}'" for 4XX errors. I am observing this issue with a 500 error. Is error 500 significant here?

@scrhartley
Copy link
Contributor

scrhartley commented Dec 19, 2024

According to docs, default handling is:

responseHandling: [
    {code:"204", swap: false},   // 204 - No Content by default does nothing, but is not an error
    {code:"[23]..", swap: true}, // 200 & 300 responses are non-errors and are swapped
    {code:"[45]..", swap: false, error:true}, // 400 & 500 responses are not swapped and are errors
    {code:"...", swap: false}    // catch all for any other response code
]

So there should be no difference between 4xx and 5xx errors.

The response-targets extension can change the isError value, so possibly it's always setting it to false:

isError flag on the detail member of an event associated with swapping the content with hx-target-[CODE] will be set to false when error response code is received. This is different from the default behavior. You may change this by setting a configuration flag htmx.config.responseTargetUnsetsError to false (default is true).

Possibly also need to set event.detail.shouldSwap to true, although this may already be handled by the response-targets extension.

You can get value event.detail.xhr.status for response code number.

Here is how htmx matches status code:

function codeMatches(responseHandlingConfig, status) {
    var regExp = new RegExp(responseHandlingConfig.code)
    return regExp.test(status.toString(10))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants