Infinite scroll turbo stream and initializing 3rd party JS libs

Hi,

I just set up Bearer | Infinite scrolling pagination with Rails, Hotwire, and Turbo and it’s working really well.

Except I have some content that requires Anime.js (https://codepen.io/favoriteusername/pen/BaPwzRM) and struggle to get it working inside the infinite scroll turbo stream.

I came across Event to know a `turbo-stream` has been rendered and tried copy/pasting my JS into app/javascript/controllers/infinite_scroll_controller.js:

import ApplicationController from "./application_controller";
import { useIntersection } from "stimulus-use";

import anime from "animejs";

export default class extends ApplicationController {
  static targets = ["button"];

  connect() {
    super.connect();
    useIntersection(this, { element: this.buttonTarget });

    var wave = anime
      .timeline()
      .add({
        targets: ".wave path",
        strokeDashoffset: [anime.setDashoffset, 0],
        delay: function (el, i) {
          return i * 250;
        },
        easing: "easeInOutSine",
        duration: 600
      });
  }

  appear() {
    this.buttonTarget.disabled = true;
    this.stimulate("InfiniteScroll#load_more", this.buttonTarget);
  }
}

app/views/posts/index.html.erb

<div id="posts">
  <!-- Turbo infinite scroll -->
</div>

app/views/posts/index.turbo_stream.erb

<%= turbo_stream.append "posts" do %>
  <%= render partial: "posts/list", locals: { post: @posts } %>
<% end %>
<% if @pagy.next.present? %>
  <%= turbo_stream.replace "pagination" do %>
    <%= turbo_frame_tag "pagination", src: posts_path(page: @pagy.next, format: :turbo_stream), loading: :lazy %>
  <% end %>
<% end %>

But to no avail. What should I do?

Are you trying to show an animation while the turbo frame is loading, or after the frame is loaded?

After. I also have other custom JS that needs to run after each stream, but unfortunately turbo:frame-render or similar doesn’t seem to offer a solution.

In your code example, I do not see where you are injecting the stimulus controller and actions in the html.erb

I’m not sure what you mean, the posts appear on the page as expected however their JS never starts :confused:

Somewhere in the html I expect to see data-controller=“infinite-scroll” where the controller is initialized. I don’t see it anywhere.

True that, I thought about that once but I didn’t see it in the tutorial (Bearer | Infinite scrolling pagination with Rails, Hotwire, and Turbo) so I figured it wasn’t needed :person_shrugging:

I suggest reading the hotwire stimulus documentation:

https://stimulus.hotwired.dev/handbook/introduction

I might have done a terrible job at explaining myself though. Can you please gve me some hints where to put this so it will also run on new .banner elements coming from turbo streams?

// app/javascripts/application.js
import "@hotwired/turbo-rails"
import "./channels"
import "./controllers"

import anime from "animejs"

$(document).on("turbo:load", function() {
  if($(".banner").length) {
    var wave = anime
      .timeline()
      .add({
        targets: ".wave path",
        strokeDashoffset: [anime.setDashoffset, 0],
        delay: function (el, i) {
          return i * 250;
        },
        easing: "easeInOutSine",
        duration: 600
      });
  }
}

Thanks!

I tried

// app/javascripts/application.js
addEventListener("turbo:after-stream-render", ((event) => {
  const fallbackToDefaultActions = event.detail.render

  event.detail.render = function (streamElement) {
       var wave = anime
      .timeline()
      .add({
        targets: ".wave path",
        strokeDashoffset: [anime.setDashoffset, 0],
        delay: function (el, i) {
          return i * 250;
        },
        easing: "easeInOutSine",
        duration: 600
      });
  }
}))

from Turbo Handbook to no avail…