Router passing wrong model/context to setupController


#1

I don’t know if I should ask this here but SO hasn’t been very helpful.

I wrote a small custom data library for my Ember app, and I am having problems with my model being set correctly. Take the following example:

App.UserRoute = Ember.Route.extend
  model: (params) ->
    user = App.User.find(params.user_id)
    console.log "model:", user
    return user

  setupController: (controller, model) ->
    console.log "setupController:", model
    controller.set('content', model)

Console Output:

#=> model: Class {id: '1', ...}
#=> setupController: Object {user: Object, groups: Array}

The first is the correct model object as expected, but setupController is passed the JSON response to the ajax call made during the App.User.find() call. I think this is the most likely culprit, but I don’t understand how to fix it:

App.Model.reopenClass
  find: (owner, id) ->
    [owner, id] = parseArguments(2, arguments)
    store = App.Store.storeForType(@)
    return store.find(id) if store.hasRecord(id)
    record = store.initializeRecord(id)
    App.Client.find(record, id, owner)
    record

App.Client = Ember.Object.create    
  find: (record, id, owner) ->
    url = @_buildUrl(record, id, owner)
    @request(url, null, "GET").promise(record).then (json) ->
      App.Store.load(json)
      record.didFindRecord()

  request: (url, data, method) ->
    deferred = jQuery.Deferred()
    params = {..}
    params.success:  (json)  -> Ember.run(null, deferred.resolve, json)
    params.error:    (jqXHR) -> Ember.run(null, deferred.reject, jqXHR)
    params.always:           -> Ember.run(null, deferred.always)    
    jQuery.ajax(params)
    return deferred

I am using jQuery.Deferred() to make use of it’s always callback, but still I don’t see why the route would change it’s context. Does anybody have any idea why this is happening?


#2

Assuming App.User.find(params.user_id) returns a thennable (object with a .then property), it seems that some reason that .then is resolving to the Object {user: Object, groups: Array} thing you see. This is new router stuff in action; the router will pause for thennables and ultimately use the object that the thennable resolves to. Perhaps you’re doing something custom with .find() that causes the .then to resolve to something else? Not sure.


#3

Just read the RC6 release notes and this is exactly what’s happening. I ended up including the Ember.DeferredMixin in my Model object and returning the record from jQuery’s deferred.done callback so I could resolve the actual record, not the the JSON returned from the request. Thanks a bunch.