ruby-on-railsrubyhamlrails-ujs

Rails-UJS response rendering raw html instead of interpreted haml


I am implementing an infinite-scroll feature using the kaminari gem for pagination and rails-ujs.

The partial loads fine on the initial page view. It displays the results (each result is a card rendered from a partial called ‘rooms_card.html.haml’

Rendering the rooms_card partial on the index.html.haml page as a collection.

= render partial: "rooms_card", collection: @rooms, as: :room, cached: true

initial page render

However, when I click on the ‘View More’ link, the request is made and the result is appended, but it is raw html displayed instead of interpreted.

raw html appended instead of rendered

Here is the code for the link.

= link_to_next_page @rooms, "View More", class: "view-more-link", remote: true}

From my index.js.haml file

document.getElementById("rooms-cards").append("#{j render(partial: "rooms/rooms_card", collection: @rooms, as: :room) }")

My respond to block. rooms_controller.rb

    respond_to do |format|
      format.js
      format.html
      format.json { render json: @results, each_serializer: RoomSerializer }
    end

How can I get response to render in the browser instead of displaying the raw html?

I have squinted at this everyway I know how. Any ideas on what I am missing?

Thank you!

Dave


Solution

  • If you pass a String (DOMString to be precise) object to the append method, it will be inserted as a Text node. Pass a Node object instead.

    const wrapper = document.createElement('div');
    wrapper.innerHTML = "#{j render(partial: 'rooms/rooms_card', collection: @rooms, as: :room)}"
    document.getElementById("rooms-cards").append(wrapper);
    

    If you don't want to create an additional div, you can use DocumentFragment.

    const fragment = document.createDocumentFragment();
    fragment.innerHTML = "#{j render(partial: 'rooms/rooms_card', collection: @rooms, as: :room)}"
    document.getElementById("rooms-cards").append(fragment);
    

    Hope this helps.