Why won't my templates render after adding a parent route?


#1

To add authentication to an existing application using Ember Simple Auth I have retrospectively split my routes as follows:

//router.js

 Router.map(function() {
  this.route('authenticate', { path: '/' }, function() {
    this.route('route1', function() {
      this.route('nestedroute1', function() {
        this.route('nestednestedroute1');
      });
      this.route('route2', function() {
        this.route('nestedroute2');
        this.route('nestednestedroute2');
      });
      this.route('route3');
      this.route('route4');
    });
});
this.route('login');
});

The idea is that the routes under authenticate will use the layout in the authenticate.hbs file and my login page can use the standard application.hbs.

It kind of works. My login page has a unique layout and when I log in, I am passed to the layout laid out in authenticate.hbs:

//authenticate.hbs
<div id="page-container" class="fade page-sidebar-fixed page-header-fixed page-with-light-sidebar">
	{{layout/top-bar}} {{layout/side-bar}}

	<div id="content" class="content">
		{{outlet}}

	</div>
	<a href="javascript:;" class="btn btn-icon btn-circle btn-success btn-scroll-to-top fade" data-click="scroll-top"><i class="fa fa-angle-up"></i></a>

</div>

However, clicking any of the links in the sidebar component do not render the new template in the {{outlet}} of the authenticate.hbs. The URL in the browser address bar changes but no template is rendered on the screen.

I can’t work out why. My application.hbs only contains an {{outlet}} with nothing else. I tried changing the {path: ‘/’} in the authenticate route to {path: ‘/authenticate’} but then receive unrecognised URL errors.

I considered that I might need to use named outlets but this seems to anything rendering correctly.

Any pointers would be greatly appreciated.


#2

I’ve actually managed to solve this!

They key is to use {resetNamespace: true} on the various parent routes. I’m not sure of the WHY but it has certainly resolved the problem.

//router.js

 Router.map(function() {
  this.route('authenticate', { path: '/', resetNamespace: true }, function() {
    this.route('route1', {resetNamespace: true},  function() {
      this.route('nestedroute1',  {resetNamespace: true}, function() {
        this.route('nestednestedroute1');
      });
      this.route('route2', {resetNamespace: true}, function() {
        this.route('nestedroute2', {resetNamespace: true});
        this.route('nestednestedroute2');
      });
      this.route('route3', {resetNamespace: true});
      this.route('route4', {resetNamespace: true});
    });
});
this.route('login');
});

If someone would be willing to explain why this works I’d be really grateful


#3

When you moved your routes under a new parent route, that renamed all the routes. So route1 became authenticate.route1.

resetNamespace disables that renaming behavior, which is why it solved your problem. In general I would only recommend using it when it’s really needed, which is mostly when routes are coming out of some library that can’t know in advance where it’s going to be mounted.

To avoid needing resetNamespace you need to find things like {{link-to 'route1'}} and update them to {{link-to 'authenticate.route1'}}, and you need to move your files like:

  • app/templates/route1.hbs to app/templates/authenticate/route1.hbs
  • app/controllers/route1.js to app/controllers/authenticate/route1.js