How do I enable infinite scrolling on third party data?


#1

Hello,

I am trying to build a product discovery app with the Stripe API and I am trying to publish product data to a client-only mongo collection. I am trying to enable infinite scrolling, where if the user scrolls all the way to the bottom of the page, the limit increases in the publication. The publication also needs to update every few seconds just in case other users update their product data.

I was able to enable interval updates, however; I was unable to enable infinite scrolling.
Here is my code:

SERVER SIDE:

const PRODUCT_INTERVAL = 5000;
const Stripe = require("stripe")(Meteor.settings.private.stripe.secret);

Meteor.publish("stripe-products", function(limit){
  
  const self = this;
  const publishedKeys = {};

  const stripeAccount = Shops.findOne({"users.userId": this.userId}, { fields: { "stripe.external_account.accountId": 1 }});
  async function getStripeProducts(){
    try {
      const getStripeProducts = await Stripe.products.list(
        {limit: limit},
        {stripe_account: stripeAccount.stripe.external_account.accountId}
      );
      return getStripeProducts.data;
    } catch(exception){
      console.error(exception);
    }
  }
  
  async function saveStripeProductsIntoClientDatabase(userId){
    const stripeProducts = await getStripeProducts();
    stripeProducts.forEach((product) => {
      const findUserShop = Shops.findOne({ "users.userId": userId}, { fields : { "_id": 1}});
      const findExistingProduct = Products.findOne({ "_id": product.id, "shopId": findUserShop._id});
      if(!findExistingProduct){
        if(publishedKeys[product.id]){
          self.changed("stripe-products", product.id, product);
        } else {
          publishedKeys[product.id] = true;
          self.added("stripe-products", product.id, product);
        } 
      }
    });
  }

  saveStripeProductsIntoClientDatabase(self.userId);
  self.ready();

  const interval = Meteor.setInterval(function(){
    saveStripeProductsIntoClientDatabase(self.userId);
  }, PRODUCT_INTERVAL);

  this.onStop(() => {
    Meteor.clearInterval(interval);
  })
});

CLIENT-SIDE:

Session.set("limit", 20)
Template.view_inventory.onCreated(function(){
          this.autorun(() => { 
                this.subscribe("stripe-products", Session.get("limit"))
          });
});

$(window).scroll(function() {
   if($(window).scrollTop() + $(window).height() == $(document).height()) {
       Session.set("limit", Session.get("limit") + 10)
   }
});

#2

Rather than using async/await like this, which overcomplicates the code, why not use Meteor.wrapAsync to make the Stripe functions synchronous?