Paginating a Backbone collection

Posted on

Problem

This is part of a class for paginating a Backbone collection.

The paginateTo method is for paginating to a model id. It returns the model if it’s already in the collection, otherwise it checks with the server that it exists. If so, it requests subsequent pages until it’s loaded into the collection.

How would you refactor this method to make it clearer?

paginateTo: (id, dfd, check) ->
  dfd ?= new $.Deferred
  return dfd.resolve(model) if model = @get(id)
  check ?= @checkModelExists(id)
  check.done =>
    @once 'sync', => @paginateTo(id, dfd, check)
    @fetchNextPage()
  check.fail =>
    dfd.reject()
  dfd.promise()

checkModelExists: (id) ->
  url = @url() + '/' + id
  $.get url

fetchNextPage: ->
  @page += 1
  @fetch { update: true, remove: false, data: { page: @page }}

Solution

You could do something like this

paginateTo: (id) ->
  deferred   = new $.Deferred
  modelCheck = null

  modelExists = =>
    modelCheck or= @checkModelExists id

  fetchUntilFound = =>
    return deferred.resolve model if model = @get id
    modelExists().fail deferred.reject
    modelExists().done =>
      @fetchNextPage().then fetchUntilFound, deferred.reject

  fetchUntilFound()
  deferred.promise()

Leave a Reply

Your email address will not be published. Required fields are marked *