Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how would you build pinterest like page with meteor.js

I hope all of you know the pinterest style layout and its behaviour:

  • we have collection of many (let's say 1000) products
  • on page load we display only little subset of that collection (i.e. 20 first products)
  • when user scrolls down and reach bottom of the page, we render next 20 products
  • page is viewed by many clients, and each has its own set of displayed products

Bonus task:

  • when Products collection gets new items, they are displayed on top of the page (as first items in displayed products list)

I am thinking how to program that logic in Meteor way. Let's skip user interface code, I am interested only in business logic.

I am thinking about ProductsDisplayed collection as helper, which is empty and populated by 20 products on page load, then when scrolling point is reached, I insert 20 products more from original Products collection etc.

Problems:

  • how to have different ProductsDisplayed collections between clients,
  • how to ask for next 20 products from Products collection, and don't get the previous ones

But maybe the whole idea about ProductsDisplayed is wrong. I would love to know what do you think!

Update!
I changed approach to using only Products collection.

server:

Meteor.publish "productsDisplayed", (number) ->
  Products.find {},
    limit: number

client:

Meteor.autosubscribe ->
  Meteor.subscribe "productsDisplayed", Session.get('productsDisplayedNumber')

and incrementing by 20 Session 'productsDisplayedNumber' when scrolling point reached. But autosubscribe makes that the whole template is rerendered, not only the new elements. Any ideas?

like image 576
krzysu Avatar asked Feb 05 '13 11:02

krzysu


1 Answers

I finally solved this problem. The solution is to have client only Collection, like that:

# on client
# client side only collection
ProductsDisplayed = new Meteor.Collection(null)

then when scrolling point is reached ask server for next N (limitNo) products

# on client
Meteor.call 'getProducts', limitNo, skipNo, (err, products) =>

  _.each products, (item, index) =>
    # get rid of _id
    delete item._id

    ProductsDisplayed.insert( item )

skipNo is incremented by N, to always ask for next set of data. And on server side I have:

# on server
Meteor.methods
  getProducts: (limitNo, skipNo) ->

    productsCursor = Products.find( {}, {
      limit: limitNo,
      skip: skipNo
    })

    productsCursor.fetch()

this Meteor method returns me next set of products from Products collection.

Of course view template displays ProductsDisplayed collection content:

Template.products.products = ->
  ProductsDisplayed.find {}

So, what do you think?

like image 51
krzysu Avatar answered Nov 02 '22 23:11

krzysu