After watching @chrismccord’s excellent “The Road To LiveView 1.0” keynote, the upcoming infinite scroll features with :limit on streamed collections looked like exactly what I needed to simplify the implementation of something I’m working on. I introduced LiveView to this project a while before it was even available on Hex, so I’m happy enough to depend on main to get the new features before 0.19 gets released.
However, my phx-viewport-top and phx-viewport-bottom events don’t seem to be triggering. Apart from switching my phoenix_live_view dependency to use github and adding those attributes to an element that has phx-update="stream", is there another step that I’m missing?
This is what’s in my template, with some irrelevant things removed or renamed:
Are you sure you’re on latest main? I didn’t merge the viewport branch stuff until recently.
Pretty sure – I only switched to tracking main and ran mix deps.get yesterday (I noticed that the branch was merged a few days ago). I can see Hooks.InfiniteScroll in app.js, so it looks like it’s compiling the right assets.
I’ll try creating a clean app and see if that works, and work from there. There’s almost certainly something obvious I’m missing!
Maybe you need to clean some JavaScript cache or similar so it picks up the latest JS bundle from LiveView?
Thanks – honoured to have two such esteemed people reply to my post
I think I cleared all the caches (removed and rebuilt priv/static, and did an “empty cache and hard reload” in Chrome), but not 100% sure I got everything. I’ll keep digging!
Update – the test liveview that worked in a new app didn’t when I dropped it into the old one, so I suspected it was something to do with the asset-building process. The old app is still using Webpack, along with an ancient version of node.js and what seems like far too many npm packages, and when I tried installing esbuild instead the events suddenly started getting through OK. Time to bite the bullet and finally switch, I guess (it had been left as-is up to now to avoid figuring out how to get sass, bootstrap etc working with esbuild).
I believe the issue is with some assumptions on the InfiniteScroll hook.
Look at this two lines of code (taken from InfiniteScroll):
window.addEventListener("scroll", this.onScroll);
var scrollTop = () => document.documentElement.scrollTop || document.body.scrollTop;
In my case, where the stream is inside an absolutely positioned element, the scroll event is not triggered at the window level, and document.body.scrollTop returns always zero.
Thanks @fceruti, that definitely looks like it’s related to the issue I was having. My liveview was inside a grid layout, which ended up with the immediate parent appearing to have a height big enough to fit its content, with the scrolling happening further up the dom. I think the culprit was actually a footer which is a LiveComponent, with the generated phx-root div somehow confusing things. I ended up reworking the layout, and rendering the <footer> element in the layout instead of the component, and eventually managed to end up with the phx-update="stream" element having 100% height and the scroll events reaching the hook correctly.
My assumption that Webpack was somehow to blame was a complete red herring, but on the plus side I now have a nice clean asset build with esbuild, dart-sass and phoenix-copy, and a much cleaner node_modules directory! Somewhat reminiscent of when I migrated the same app from brunch to webpack, and from bootstrap 4 to 5 a few years ago, only to find that the thing that was actually causing brunch to fail had been a missing semicolon in a config file somewhere .