There is already a Dashboard.UserController. But at the moment it extends Ember.Controller. I change this to Ember.ObjectController so we can set the content of the controller to a specific Dashboard.User instance and everything is proxied to the content. To get a specific user the find method on the GitHubAdapter needs to be modified accordingly:

Alright, everything is basically set up to retrieve a user: let’s use it in the router and adapt the templates accordingly. Currently the route to a user is specified as /:username, and in the connectOutlets it is retrieved via context.username. If we change this to /:user_id Ember.js assumes that we are referencing a Dashboard.User model. It will automatically find this user with the passed id via Dashboard.User.find() and pass this model as context to the connectOutlets. The router therefore can be adjusted like this:

Because the user is fetched asynchronously, it may not be available already in the sub-routes index and repository. So router.get('userController.login') may be null. To circumvent this we get the username via router.get('userController.id'). This works since the primaryKey in the Dashboard.User model has been set to login and it seems that id is set when Ember.js resolves the /:user_id route. I’m honestly not sure if this is the intended solution and I will investigate in the correct way of doing this and update the code.

Last step to show the user: add and modify the existing templates. I created a user template which shows the information for a specific user. It also has a watchedRepositories outlet which get’s connected with the watchedRepositories:

Dashboard.Router=Ember.Router.extend({root:Ember.Route.extend({index:Ember.Route.extend({route:'/',connectOutlets:function(router){router.transitionTo('user.index',Dashboard.User.find('pangratz'));}}),user:Ember.Route.extend({route:'/:user_id',connectOutlets:function(router,user){router.set('userController.content',user);},index:Ember.Route.extend({route:'/',connectOutlets:function(router){varusername=router.get('userController.id');varstore=router.get('store');// get watched repositories for given usernamevarwatchedRepositories=store.findQuery(Dashboard.Repository,{username:username,type:'watched'});// set watched repositories on repositoriesControllerrouter.set('repositoriesController.content',watchedRepositories);// connect user and watched repositoriesrouter.get('applicationController').connectOutlet('user');router.get('userController').connectOutlet('watchedRepositories','repositories',watchedRepositories);}}),repository:Ember.Route.extend({route:'/:repository',connectOutlets:function(router,context){varusername=router.get('userController.id');varrepoName=context.repository;// fetch repo for current uservarrepo=router.get('store').find(Dashboard.Repository,'%@/%@'.fmt(username,repoName));router.set('repositoryController.content',repo);varevents=router.get('store').findQuery(Dashboard.Event,{username:username,repository:repoName});// connect repository and eventsrouter.get('applicationController').connectOutlet('repository');router.get('repositoryController').connectOutlet('events','events',events);}}),showUser:function(router,evt){varusername;varcontext=evt.context;// context is a Dashboard.RepositoryController if this action// is called from repository template --> this needs to be fixedif(Dashboard.RepositoryController.detectInstance(context)){username=context.get('owner.login');}else{username=context;}router.transitionTo('user.index',Dashboard.User.find(username));},showRepository:function(router,evt){// context is the full_name of a repository: username/repositoryvarsplit=evt.context.split('/'),username=split[0],repository=split[1];router.transitionTo('user.repository',Dashboard.User.find(username),{repository:repository});}})})});

Roundup

A new model Dashboard.User has been introduced. The existing /:username route has been modified to /:user_id so Ember.js can derive which model shall be fetched and automatically set it as context in the route’s connectOutlets method.