How to use Turbo to send a json response and receive similar to ajax:complete?

Hey all, just updated my app to Turbo from rails/ujs and turbolinks. Everything is working except a bunch of ajax stuff and I was hoping to have some guidance on how to update it please.

The setup is really basic:

  1. Create a link with remote: true
= link_to get_things_path(param: another_thing.id), class: 'my-ajax-link', remote: true
  1. Server receives the ajax request on the get_things_path. Backend things happen and some json data is put together. This is not always straight HTML rendered as a string.
def get_things
  # some db stuff, some if/else logic ...
  render json: { data: 'stuff' }
end
  1. JS event listener that has been setup to receive the ajax request fires and reacts to the json data.
let my_ajax_links = document.querySelectorAll('.my-ajax-link');
my_ajax_links.forEach(function (link) {
    link.addEventListener('ajax:complete', my_ajax_click);
});

function my_ajax_click(event) {
  // lots of complex logic in multiple functions reacting to json data and then manipulating the dom happens. 
}

My problem is that the json data is just rendering as text, the ajax:complete event does not fire. I really don’t want to rewrite all this js code - is there a way to make a turbo frame or stream function with this structure?

Ideally (the Hotwire-way) would be to do the calculations on the server and the return whatever/however to the browser.

If that is not possible (you are using some JS library, I assume), I would look into turning this into a Stimulus controller instead. From there you can request the json and then render however/wherever you want.

Thanks for your response! No I’m not using a js library, there’s just a lot of complex dom manipulation that happens based on what is returned from the server (which also has some backend logic).

Could you elaborate on “return whatever/however to the browser” please? I’m wondering what the hotwire way would be to return json data and then intercept it and react in my custom javascript module since it seems ajax:complete does not fire. Could you do something like this with turbo frames? Or would this be a stream? Custom stream action?

You would move your JS logic into a stimulus controller that sends the json request using fetch/axios/etc and handle the response purely in JS. You can have a click trigger the Ajax request using a stimulus action.

+1 @Josh_Marchello says.

Turbo frames, nor -streams are meant for this. Using Stimulus is the hotwire-way here (based on the info I have).

1 Like