3
\$\begingroup\$

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 }}
\$\endgroup\$
1
  • \$\begingroup\$ What you you find complicated about it or what do you dislike about this code? The only thing I really dislike is that the internals of the paginateTo function are indirectly exposed via the function's signature, which also breaks encapsulation. You should perhaps use an IIFE to declare a private method to be called recursively instead. \$\endgroup\$
    – plalx
    Oct 11, 2013 at 4:16

1 Answer 1

1
\$\begingroup\$

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()
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.