Why is 'application' not working in a subroute in Ember? - ember.js

I'm developing an Ember frontend which has to handle an 'application' resource.
My router looks like this:
this.route('applications', function() {
this.route('application', { path: ':application_id'}
);
);
I get the following error:
Assertion Failed: 'application' cannot be used as a route name.
This seems to conflict with 'application' route of the Ember application.
Changing the route name from 'applications/application' to 'applications/app' works, but this is not very elegant.
Does anybody know if/why a subroute can never be '.../application/...'?
Thank you!

I would imagine that this had to do with the fact that application is the top level route of the entire application in EmberJS. It is a reserved keyword in the framework and can't be used for anything other than its purpose that has been set out by EmberJS.

Related

Combining two emberjs apps

I am currently using ember 1.13. I have two apps which use emberjs. Now I am thinking of integrating these two apps by creating a new route in the first app and display specific route of the second app. Many suggested to use ember-engines,but they need ember 2.10 or higher.Since my application mostly depends on IE 8,I cannot migrate from ember 1.x.
So what should I do? Thanks in advance!!
Cheers!!!
So one approach that would work pre engines is to leverage an addon for the common routes. Your addon will define routes, controllers, and templates as usual with the addons directory. You will also want to define something like addons/utils/router-utils:
// assume we have a single route foo
export function addRoutes(router) {
router.route('foo');
}
router is the this value that ember provides when invoking Router.map. So, within your addon, to allow for "normal" feeling development, you'll want to use this addRoutes function within the dummy app router in tests/dummy/app/router.js:
import EmberRouter from '#ember/routing/router';
import config from './config/environment';
import { addRoutes } from 'addon-with-routes/utils/router-utils';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
addRoutes(this);
});
export default Router;
Note well, the above router.js file is what Ember 3.8 generates. Yours will most likely differ but the key point is that we invoke our addRoutes function with the anonymous Router.map this value to dynamically add our routes to the dummy app. See this twiddle for an example of adding routes to the router dynamically.
You can now run ember serve from within the addon project and test your routes. Acceptance tests run against the dummy app as well so you're not really constrained by this approach.
Now within your consuming app, you would do the same thing we did in the dummy app to add the routes. This approach, in general, though will require careful engineering to work effectively (a lot of the problems that ember engines solves must be solved by you in some way). Your addon will most likely have to expose a lot of configuration so that you can route outwards from the addon back into the consuming app which will not know about the routes in the consuming app. You'll have to avoid namespace collisions. Sounds fun though :)

Ember 2.5 Application Controller not present?

This is a very simple and probably easily resolved one.
I have created an emberjs application controller via ember generate controller application from which I want to return some basic computed properties based on the current path to higher level controllers and components. Basically, something like this:
export default Ember.Controller.extend({
entity: Ember.computed('currentPath', () => {
return this.get('currentPath').split('.')[0];
})
});
Oddly enough, I cannot access these computed properties anywhere (they turn out undefined, even if I replace them with a debug string), and in the Ember Inspector's view tree, the application controller is apparently not even present:
I have an older Ember 1.13.0 app, where I'm using the application controller with no difficulty. Have I missed a deprecation here? Or do I need to register the application controller in a specific location?
okay, I solved this differently using injection of the routing service directly into the component (see Component to be notified on route change in EmberJS 2 for details)

Service is undefined?

I have just started working with ember2.5.1. I wanted to try and create an easy service, and have a component implement it. The problem is that the service is always undefined, and I can't seem to call its methods.
/components/status-component.js
import Ember from 'ember';
export default Ember.Component.extend({
logger: Ember.inject.service(),
actions: {
test() {
this.get('logger').log("testing");
}
}
});
/services/logger.js
import Ember from 'ember';
export default Ember.Service.extend({
log(message) {
console.log(message);
}
});
Other information: I also attempted making routable components, and I'm not sure if that's messing up the services? I essentially have a route pointing to a dummy status-proxy-component.hbs which has the {{status-component}} within it. status-component.hbs is another file.
Any idea why this might not be working? Am I just plain out missing something from services, or is the proxy messing it up?
You must use the get() function to get component properties.
this.get('logger').log("testing");
I had the same problem with Ember 2.4.2; the service was defined in the correct location and would appear in the ember build output, but not in my running ember serve.
The problem turned out to be the hot reloading not picking up on the new service. Killing the server and re-running ember serve allowed the service to work normally.

How do you update a controller from another controller in ember.js?

In my application I have common header that outlets into the main application layout. In that header you can select a site. I need that site selection to update another template that is rendered in the application layout. Having struggled with this for a few days I think the correct way to solve this is to use a shared service, to have the header controller observe the site selection and set that value in the shared service, then to have the index controller use a Ember.computed.alias on the value in the service controller. The following is an example of my code:
controllers/header.js
import Ember from 'ember';
export default Ember.Controller.extend({
sessionService: Ember.inject.service(),
currentSiteChanged: Ember.observer('session.current_site', function(){
var current_site = this.get('session.current_site');
console.log('currentSiteObserver', current_site);
this.get('sessionService').set('currentSite', current_site);
}),
});
controllers/index.js
import Ember from 'ember';
export default Ember.Controller.extend({
sessionService: Ember.inject.service(),
currentSite: Ember.computed.alias('sessionService.currentSite'),
dashboardData: function(){
var currentSite = this.get('currentSite');
console.log("in dashboardData", currentSite);
//other code that uses the currentSite
}.property('currentSite'),
});
services/session-service.js
import Ember from 'ember';
export default Ember.Service.extend({
currentSite: null,
setCurrentSite: function(){
var currentSite = this.get('session.current_site');
this.set('currentSite', currentSite );
}.on('init'),
});
I think this should allow someone to select a site in the header and have the dashboardData property in index update to use that selection. When the page initially loads the header defaults to the first site and the index renders it has the correct site value that it must have gotten from the session-service, however if you select another site the index does not get updated. Via the console.logs and debugging I can see that the header is observing the change and setting the value on the session-service.
Additionally I have tried solving this other ways (injecting the header service into the index and observing a property, injecting the index in the header and directly setting the value, sending and listening to events,etc) but I am willing to try anything or to be corrected that this isn't the correct way to solve the problem.
I am using ember 1.13.8 and moving to 2 isn't an option at the moment.
I don't think a service is an appropriate solution to this problem.
You want your application to have a good RESTful url design (respect for urls is a corner-stone of the Ember framework), so try to capture your application state in the URL.
Consider that if a user were to select a site, and then hit refresh they would lose their selection unless you stored it somehow in a cookie or localStorage.
I would recommend using either routes or query parameters to solve your problem.
Routes
Using routes is fairly straightforward (http://whatever.com/sites/pet-hampsters).
Query Params
You can also use query params, something like this http://whatever.com/?site=pet%20hampsters.
To do this you would write an action that bubbles up to your application controller and sets the value of the 'site' queryParam. Any of your sub-controllers on the currently active route can then read the site value with the new Ember.inject syntax. This is the conventional way to manage dependencies between controllers.

Template without application.hbs as root?

I've got an Ember-Cli App and would like to create an admin-interface for my application which looks nothing like the page set up in application.hbs.
How do I make the admin-interface independent from that one?
The way I achieved it was to have the base route and, in your case, admin route, kind of what #jcbvm was saying. So the router would look like:
this.resource('base', {
path: '/'
}, function() {
this.path('my-route');
// the rest of the app
});
this.resource('admin', {
path: '/admin'
}, function() {
// admin part
});
I think this can hardly be achieved, my best bet is to either creating a separate application for your admin interface or by moving your core application to a separate route.
When moving your core application to a separate route, you can move the contents of your application.hbs to the template of the new route and your admin interface to the admin route. The only drawback of this is that you will always see the name of your core route in the URL when going to the core application.
You should likely go down the path of Ember CLI addons, see here