Should I use setupController or model from my Routes


#1

In this simple example I have a nested route /user/:user_id/posts.

I want my UserPostsController to be passed user.get('posts') as it’s model.

The UserController already has this user loaded up as it’s own model, so I just want to say @controllerFor('user').get('model.posts')

However, I have two ways of doing this;

model: ->
  @controllerFor('user').get('model.posts')

or

setupController: (controller, model) ->
  userPosts = @controllerFor('user').get('model.posts')
  controller.set('model', userPosts)

Which of these is the better approach?

I would assume that these were in effect the same, but the former approach doesn’t work as expected (when I switch to a new user the model doesn’t get updated)

Is the failure of the model: approach a bug, or is it expected?


#2

There’s another solution that I use that seems to work well for me:

App.UserPostsController = Ember.Route.extend({
  model : function() {
    return this.modelFor("user").get("posts");
  }
});

#3

@Spencer_Price I think you made a mistake.

Is that supposed to extend Ember.Controller?

Because I tried variants of this

App.UserPostsController = Ember.Controller.extend
  model: ->
    @modelFor('user').get('posts')

And

App.UserPostsController = Ember.ArrayController.extend
  ...

But they both error out.

Assertion failed: an Ember.CollectionView’s content must implement Ember.Array

And

Uncaught TypeError: Object function () { return this.modelFor(“user”).get(“posts”); } has no method ‘addArrayObserver’


#4

Oh…Whoops! So sorry…it should be:

App.UserPostsRoute = Ember.Route.extend({
  model : function() {
    return this.modelFor("user").get("posts");
  }
});

#5

Makes sense @Spencer_Price. I get a bug with this though.

If I go to /user/1/posts then go to /user/2/posts the posts don’t refresh.

When I use setupController I don’t have this problem.


#6

How are the route transitions being triggered?


#7

The model hook is only called when coming in from a URL, not when using any of the transitionTo methods or the linkTo helper. The setupController hook, on the other hand, is always called no matter how the route was entered.

I guess I should add that the model hook is passed the URL parameters allowing you to resolve them to the actual model object.


#8

Is this true? Isn’t that only if the route has dynamic segments? If not, and no model is passed in the linkTo helper, it seems the model hook is called.

If this isn’t how it’s supposed to work, I have some code to change.


#9

Do the model hook. I’m almost positive if you attempt to do modelFor(‘userPosts’) deeper in the route it won’t exist if you don’t return it from the model hook. You could still grab the controller and model from the controller tho. (I gotta go test this and make sure I’m not lying)


#10

@kingpin2k you are correct. Return from model will allow modelFor to return the correct value mid-transition.


#11

Whoops, yeah forget that case. I always implement my model hooks from the standpoint of what do I need to do to put the application into a state to render the requested resource starting with just the requested URL. This usually starts within the application route, returning promises along the way so I’m sure everything is ready when I need it. Then all the internal transitions, modelFor’s and linkTo’s just work.