Infinite Scroll in Meteor 1.2 Using Appear Isn't Working

We implemented jQuery’s Appear into our Meteor app to work in coordination with an infinite scroll we set up for a News Collection. However, the appear logs aren’t firing correctly.

console.log(“it has appeared on scroll”) fires when you scroll from the top of the browser window to halfway

and

console.log(“it has not appeared”) fires when you scroll from halfway to the bottom of the browser window

(Method 1)

$(window).scroll(function() {
if($(’#hasMoreResults’).is(’:appeared’)) {
var func = throttle(grabMoreResults, 200);
func();
console.log(“it has appeared on scroll”);
} else {
console.log(“it has not appeared”);
}
});

See here for method 1: https://jsfiddle.net/jqL3rfyf/4/

(Method 2)

We tried an alternative method to infinite scroll using the Meteorpedia method.

function showMoreVisible() {
var threshold, target = $("#hasMoreResults");
if (!target.length) return;

threshold = $(window).scrollTop() + $(window).height() - target.height();
if (target.offset().top < threshold) {
    if (!target.data("visible")) {
        console.log("target became visible (inside viewable area)");
        target.data("visible", true);
        newsLimit.set(newsLimit.get() + 9);
    }
} else {
    if (target.data("visible")) {
        console.log("target became invisible (below viewable arae)");
        target.data("visible", false);
    }
}

}

See here for method 2: https://jsfiddle.net/maLugn7x/

The problem with this 2nd method is that it gets the next 9 but after that it breaks and just shows the loading animation.

In either case, we’re trying to use Appear to trigger the newsLimit increase by +9 and we’re using a Reactive Var to store the newsLimit.

Does anyone have a better solution for implementing an infinite scroll using Reactive Vars?

I use Semantic:UI’s API for visibility to do infinite scrolling… this is what it looks like…

HTML:

<template name='posts'>
	...
	<div id='posts-container'>
		{{#each posts}}
			{{> post}}
		{{/each}}
		{{#unless Template.subscriptionsReady}}
			{{> loading}}
		{{/unless}}
	</div>
</template>

here’s the JS:

Template.posts.onCreated(function() {
    this.state = new ReactiveDict()

    this.state.set('postLimit', 6)
    this.state.set('postSortField', 'createdAt')
    this.state.set('postSortOrder', -1)
    
    this.autorun(() => {
        let limit   = this.state.get('postLimit'),
            field   = this.state.get('postSortField'),
            order   = this.state.get('postSortOrder'),
            sort    = {[field]:order}

        this.subscribe('posts', limit, sort)
    })
    ...
})

Template.posts.onRendered(function() {
    var state = this.state

    this.$('#posts-container').visibility({
        once:false,
        onBottomVisible() {
            state.set('postLimit', state.get('postLimit') + 4)
        }
    })

EDIT - almost forgot the publish xD

Meteor.publish('posts', function(limit, sort) {
	if(!this.userId)
		return this.ready()

	return Posts.find({}, {
		sort,
		limit
	})
})

he new Meteor Guide has a section on infinite scrolling in “Data Loading”, and a related section in “UI” which you may find useful.