Ajax Lifecycle


All events bubble and are cancellable by default.

Bubbling means they will always start from the form / link that submits the event and continues upward all the way to the top of the DOM. Bubbling can be stopped via event.stopImmediatePropagation(). Events are also cancelable / preventable in the following way:

calling event.preventDefault() on an ajax event will cause it to stop running.

A form / link with the data-remote="true" attribute or a link with data-method="<method>" will fire the following events:

ajax:request:error # => Error sending the request
ajax:response:error # => 404s, 500s, etc
ajax:error # => will catch both request and response errors.
ajax:beforeNavigation # => fires before the navigation adapter, can be stopped.
ajax:stopped # => when event.preventDefault() is called or event.detail.fetchRequest.cancel(event) is called.
  • Diagram of Ajax form submissions

Screen Shot 2021-06-10 at 3 23 02 AM


All properties available on event.detail

element // => either form or link element that initiated request
fetchRequest // => FetchRequest (wrapper around Request)
request // => Request
fetchResponse // => FetchResponse (wrapper around Response)
response // => Response
submitter // => The button clicked to initiate the submit. Button / Link element
submission // => Either FormSubmission or MethodSubmission.
status // => available for ajax:success, ajax:complete, ajax:response:error, ajax:error
Warning: About remote / ajax links
<a href="#" data-method="delete" data-remote="true">
does not fire the submit event, it skips to ajax:before, this is due to to the fact that links do not actually trigger a submit event.

Cancelling Events

Cancelling Ajax events is fairly straightforward with only 1 edge case involving the ajax:send event which we will cover below.

We can cancel events at anytime by calling event.preventDefault().


document.querySelector("form").addEventListener("ajax:before", (event) => {

ajax:send is a special case and must be aborted with an abort controller. To do so, we must do the following:

document.querySelector("form").addEventListener("ajax:send", (event) => {
Warning: Be careful if we call event.stopImmediatePropagation() or event.stopPropagation(), this will prevent the ajax:stopped or ajax:completed events from firing and will leave our buttons in a disabled state that we must handle manually.