Doing infinite-scroll properly in AngularJS

Recently I wanted to make infinite scroll with Angular Material for project that I'm working on. I wanted to have header and footer with content area which is going to host content in md-list.

Note: This post is using md-list and md-list-item for demonstration purpose but you can ng-repeat anything you'd like.

I stumbled upon ng-infinite-scroll, which offers infinite scroll for AngularJS. And it worked great when I had a toolbar as header and content area which was stretching to end of the application window. But after I introduced footer which should reside in bottom, my infinite scroll broke.

After some reading, I found recommendations to use ui-scroll. But it wasn't quite the thing that I wanted, since factory is used as as data source. In my project, I'm using $resource to get data from web service, so solution with ui-scroll wouldn't work for me. In the end, I've decided to go back and take an in-depth look in ng-infinte-scroll and to come up with a solution.

What worked for me...

Here's an example how you could implement infinite scroll in your template html:

<div id="container" class="content-container content-scroll-container">  
    <md-list infinite-scroll="ctrl.loadMore()" infinite-scroll-distance='2' infinite-scroll-immediate-check='false' infinite-scroll-parent="true" >
        <md-list-item ng-repeat="contact in ctrl.contacts" ng-click="ctrl.showDetails(contact)">
...
        </md-list-item>
    </md-list>
</div>  

In your CSS define those classes:

.content-container {
    height: 300px;
}
.content-scroll-container {
    overflow-y: scroll;
}

In one sentence...

Element using infinite-scroll has to have parent element with predefined
height and overflow:scroll, and had to use (currently) undocumented infinite-scroll-parent="true".

Explanation

First, I'd like to point out the obvious: there is predefined height which must be explicitly defined. In my app this isn't the problem, but if you need variable height, I've got bad news for you: ng-infinite-scroll won't work with it.

If you're still reading, let me explain what's going on here. We are wrapping md-list in div element and using infinite-scroll-parent=true which is undocumented feature of ng-inifinite-scroll. (Same thing can be achieved with infinite-scroll-container="'#container'") If parent or container is specified, it will be used instead of window for measuring when infinite scroll is triggered.

Speaking of which, infinite-scroll defines expression to execute when user scrolls to the bottom of the list, and infinite-scroll-distance specifies how much items remain to bottom before infinite-scroll is triggered. One more thing to note is infinite-scroll-immediate-check=false which can be used when you have initial data and you don't need to fetch it immediately.

At last, in CSS we are defining size of the container which is used to measure when infinite scroll should evaluate expression. Also, we have to override default overflow-y to scroll to allow scrolling and executing infinite-scroll.

In conclusion

I'm aware that this is only partial solution since it works with fixed height. I would be really interested in some other solutions out there, or how I can improve on this one.

Cheers!

About Vjekoslav Ratkajec

Software developer from Zagreb, Croatia. Love programming, running, hiking and biking. Adore nature and animals. Also author of this blog.

Comments