Strange Turbolinks response on rails-ujs submited form inside stimulus controller

385 Views Asked by At

I'm a Rails junior developer and I recently tried to reproduce a dynamic search form from these two articles using Stimulus and rails-ujs: here and here.

Basically, it's about submitting a form query through Rails.fire in the stimulus controller, sending it to a dedicated rails controller, fetch the data from the DB and then send it back to the stimulus controller which intercepts the AJAX response. Everything works fine until it's time for my partial to be displayed. I inspected the data in the console when received by my function and I get a strange Turbolinks function instead of the content I'm expecting. I'm using Rails 6.1 and bootstrap 5.

Any idea where my problem comes from ?

My controller

class ZaagStoriesSearchController < ApplicationController

  layout false
  
  def search
    initiate_query
    render @zaag_stories
  end

  private

  def initiate_query
    query = params[:query].downcase
    if query.present? 
      @zaag_stories = ZaagStories::Search.search(query)
      authorize @zaag_stories, :show?
    end
  end
end

My form

<%= form_with url: zaag_stories_search_path,
                  local: false,
                  method: :post,
                  data: {search_target: "query", action: "ajax:success->search#handleResults"} do |form| %>
      <%= form.label :query, "Rechercher un titre" %>
      <%= form.text_field :query, data: {action:"input->search#search"} %>
    <% end %>

My view

<div class="container mt-5 wh-75 w-85" data-controller = "category-display">
  <h1 class="text-center">Mon profil</h1>
  <div class="d-flex justify-content-center my-2 flex-nowrap overflow-auto py-3" data-category-display-target="categories" id= "categories">
    <%= render @categories %>
    <button class="btn btn-secondary" data-action="click->category-display#toggleElements" data-category-display-target="button" id="category-button">
    Hide
    </button>
  </div>
  <div class="d-flex justify-content-center mb-5" data-controller= "search">
    <%= render "shared/search_form" %>
    <div class = "d-flex flex-column align-items-center mx-5" data-search-target= "results">
      <% @categories.each do |category| %>
        <h5 id="<%=category.name %>"><%= category.name %></h5>
        <%= render partial:"zaag_stories/zaag_story", collection: category.zaag_stories, as: :zaag_story %>
      <% end %>
    </div>
  </div>
</div>

My stimulus controller:

import { Controller } from "stimulus"
import Rails from "@rails/ujs"

export default class extends Controller {
  
  static targets = ["results", "query"]

  connect() {
    console.log("Hello")    
  }

  search() {
    Rails.fire(this.queryTarget, "submit")
  }

  handleResults() {
    const [data, status, xhr] = event.detail
    this.resultsTarget.innerHtml = xhr.response
  }
}

And the data I get in the handleResults()

function(){
          function renderWithTurbolinks(htmlContent){
            var currentSnapshot = Turbolinks.Snapshot.fromHTMLElement(document.documentElement);
            var newSpanshot = Turbolinks.Snapshot.fromHTMLString(htmlContent);
            var nullCallback = function(){};
            var nullDelegate = {viewInvalidated: nullCallback, viewWillRender: nullCallback, viewRendered: nullCallback};

            var renderer = new Turbolinks.SnapshotRenderer(currentSnapshot, newSpanshot, false);
            if(!renderer.shouldRender()){
              renderer = new Turbolinks.ErrorRenderer(htmlContent);
            }
            renderer.delegate = nullDelegate;
            renderer.render(nullCallback);
          }
          Turbolinks.clearCache();
          Turbolinks.dispatch('turbolinks:before-cache');
          renderWithTurbolinks("<div class=\"card my-3\" ...");
          window.scroll(0, 0);
          Turbolinks.dispatch('turbolinks:load');
        })();

And finally, the result of my partial being rendered

1

There are 1 best solutions below

0
Shrolox On

For anyone having this problem, you can add turbolinks: false param to your render function call:

  def search
    initiate_query
    render @zaag_stories, turbolinks: false
  end