Using the same URL for multiple nested ember routes


#1

I have a case using Ember where I want to make the top level URL available (ie. localhost:4200/demo), and have all the routes underneath also display the same URL (localhost:4200/demo). So the route file, if possible would look something like:

this.route('demo', function() {
  this.route('one', { path: '/' });
  this.route('submit', { path: '/' });
});

I understand that ENV.locationtype can be set for the whole app, but is there a way to conditionally set this for specific URLs underneath a parent URL?


#2

I don’t think there is any way that could work. The whole point of the router is that each URL maps to a route - and in your scenario, /demo could be either demo.one or demo.submit.

What exactly is it you are trying to accomplish?


#3

The site I’m building has been in prod for 2 years and has a requirement to display a top level URL that gives access to a starting point of a UX flow (eg. localhost:4200/start). But each of the routes underneath it should not be accessible directly from a URL. So if the flow was:

  1. localhost:4200/form
  2. localhost:4200/form/step1
  3. localhost:4200/form/step2
  4. localhost:4200/form/submit

then the URL should display localhost:4200/form throughout the entire process.

The way the app currently solves this, is by using dynamic components (don’t ask) and a custom state management system that stores an array of ‘steps’ so the user can navigate forward and back through the form. But the architecture is so tightly coupled and ‘non-emberish’, that most of the components act more like templates and can’t be re-used. I’m wanting to get back to using the routes/templates and the state service so the entire app is pulled back towards Ember conventions (also for the purposes of ease of use and relevance of Ember docs for junior or new devs).

Bear in mind the app is an extremely large govt site, and in a 9 step form, there could be 90 possible templates/components. With the current architecture, and the amount of functionality planned for the next 12 months, the size of the app is likely to balloon.

Where I’m at currently, is looking at is the private functions in Ember.HistoryLocation, and if possible I’d like to come up with a solution that can be put into a service or mixin rather than having to create a plugin with custom functionality that hijacks ember.js/packages/ember-routing.

The overall plan is to try and remove all non-ember like functionality away from the core code into plugins, and make the app itself more tightly aligned with Ember conventions.


#4

If they shouldn’t actually have different URLs, then they shouldn’t be different routes.

I think there is nothing wrong with having “route-like” components. E.g.

routes/form.js
controllers/form.js
template/form.hbs

components/form/page1.js
components/form/page2.js
templates/components/form/page1.hbs
templates/components/form/page2.hbs
// controllers/form.js
export default Ember.Controller.extend({
  currentPage: 'page1'
});
{{! templates/form.hbs }}
{{component (concat 'form/' currentPage)}}

#5

That is basically how it’s currently structured. The problem is that the components have ended up being tightly coupled instead of reusable. So we have:

components/form1/page1.js
components/form1/page2.js
templates/components/form/page1.hbs
templates/components/form/page2.hbs

components/form2/page1.js
components/form2/page2.js
templates/components/form/page1.hbs
templates/components/form/page2.hbs 

ad infinitum.

The complexity of the application has sky-rocketed. And we’re at risk of ending up with a very large download. In essence this is the core problem I’m looking to solve. Although splitting the components up a little more so the folders are more organised and human may be another approach.


#6

I agree with @francesconovy, every route has one url, and that’s it. The way to solve your problem is how you organize your components. Maybe try with pods, and keep routebale components in separte directory, that way you would have

components/routable/form/page1.js
components/routable/form/template
components/routable/form/page2.js
components/routable/form/template

and all other components could be stored in components directory. That way you’ll always know whats the component porpoise. Also if you extract all non-route logic from routable components to “normal” ones, then you’ll be able to easily reuse them.


#7

Personally, I don’t really see a problem with having some components that are very tightly coupled to a specific use case/page. Using pods/nested components helps a lot to keep that manageable, in my experience.