Search code examples
javascriptember.jsmodelroutesember-data

How to get dynamic part of currentRouteName in Ember js


I need the dynamic part of the 'model/thing/1' segment of the URL, as I'm trying to access model data in the application controller from the model currently loaded in a nested route. Is there a way to access the dynamic portion of this URL, or is there another way to somehow access this data?


Solution

  • If all you need is to display model data (or any data) somewhere else on the page (not in the current template) then you can use either ember-elsewhere or ember-wormhole.

    To access route params you can inject private routing service and use its currentState.routerJsState.params property. Property contains each available route params indexed by current route name like this:

    {
       application: {},
       test: {
          model_id: "19"
       },
       test.nested: {
          nested_id: "1"
       }
    }
    

    For instance, to display current route params we need something along these lines:

    controllers/application.js (can be component or any ember object)

    import Ember from 'ember';
    
    export default Ember.Controller.extend({
       routing: Ember.inject.service('-routing'),
    
       params: Ember.computed('routing.currentState', 'routing.currentRouteName', function() {
           let allParams = this.get('routing.currentState.routerJsState.params');
           let routeName = this.get('routing.currentRouteName');
           return allParams[routeName];
       }),
    
       jsonParams: Ember.computed('params', function() {
           let params = this.get('params');
           return JSON.stringify(params);
       })
    });
    

    templates/application.hbs

    <div>params={{jsonParams}}</div>
    

    The other option would be to create a service and populate it with required data in afterModel hook in relevant routes.

    services/data-service.js:

    import Ember from 'ember';
    
    export default Ember.Service.extend({
    });
    

    Nested route:

    routes/nested.js

    import Ember from 'ember';
    
    export default Ember.Route.extend({
       dataService: Ember.inject.service('data-service'),
    
       afterModel(model, transition) {
          this.get('dataService').set('model', model);
       }
    });
    

    controllers/application.js:

    import Ember from 'ember';
    
    export default Ember.Controller.extend({
       dataService: Ember.inject.service('data-service')
    });
    

    templates/application.hbs:

    <div>{{dataService.model}}</div>
    

    Since you probably do not want to display this data in all routes, then you can inject routing service and use currentRouteName property to decide when to show it.