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()