Ember Cannot read property 'shouldSupercede' of undefined with a new route - ember.js

I've simply added a new route to my application and when I transition to it Ember throws the error "Cannot read property 'shouldSupercede' of undefined".
Here is my router:
App.Router.map ()->
#resource 'pages', ->
#resource 'page', {path: ':page_id'}, ->
# lots of routes under here, all work
#route 'design' # new route that error happens when transition to
I started looking through the router code but I'm really not sure what's going on and hoping that there is something obvious that I'm missing. If I add some logging inside ember the error is actually thrown when it's doing some lookup on the page route here, but again that route itself works fine.
Also it doesn't matter if I'm transitioning from the page route or not, if I just reload the page with it already at the design route I get the same error:
Transitioned into 'design' ember.js?body=1:14464
Uncaught TypeError: Cannot read property 'shouldSupercede' of undefined

One reason for this issue is a {{#link-to}} pointing at a route that has a dynamic segment without providing that segment.
The error message was definitely not very helpful in pointing in the right direction unfortunately.

I was having this issue when I had a route with a dynamic segment and was not passing a value to that dynamic segment. Is there really no way to make an optional dynamic segment in Ember? may be useful to you.

I started digging into the issue with the helpful message of DEfusion.
It turns out that I have some links like: {{#link-to product.show product}}.
So I've converted all such links to this: {{#link-to product.show product.id}}. And my issue was solved.
Also you may want to check all usages with replaceWith, replaceRoute and transitionTo

Related

ember data model is not reloading even after queryParams is changing

I want my model to reload when the queryParams has changed. queryParams change is reflecting in the URL but model reload is not happening. I followed the ember.js guides (https://guides.emberjs.com/v2.6.0/routing/query-params/) on making full-on transition. I've my queryParams declared in my controller
//controllers/service/service.js
import Ember from 'ember';
export default Ember.Controller.extend({
queryParams:['showFriends']
});
//routes/service/service.js
model(params){
return this.store.query('service', params);
},
actions:{
updatePage(params){
this.transitionTo('service',{queryParams:{showFriends:params}});
},
},
queryParams:{
showFriends:{
refreshModel:true
}
},
I'm calling updatePage from a component which passes params as true or false based on a checkbox selection. The component is called from application.hbs file as below
{{test-component model=model updatePage="updatePage"}}
If I remove refreshModel:true from my route, I see the URL is updating but my model is not reloading (as expected according to the docs).
Since, I'm doing a full-on transition I added the line refreshModel:true which gives me error
ember.debug.js:32096 TypeError: this.refresh is not a function
at Class.queryParamsDidChange (ember.debug.js:26286)
at Object.triggerEvent (ember.debug.js:28580)
at Object.trigger (ember.debug.js:53473)
at fireQueryParamDidChange (ember.debug.js:52255)
at Object.queryParamsTransition (ember.debug.js:51983)
at Object.getTransitionByIntent (ember.debug.js:51913)
at Object.transitionByIntent (ember.debug.js:52018)
at doTransition (ember.debug.js:52590)
at Object.transitionTo (ember.debug.js:52087)
at Class._doTransition (ember.debug.js:28291)
I spent more than 2 days on this issue but of no use. Anybody who has faced this similar issue or has any idea on how to solve this would be a great help to me. Thanks in advance
Put queryParams:{
showFriends:{
refreshModel:true
}
} in corresponding route.
Routes are responsible for fetching models, so it should be there
Answering my own question, thought if somebody is facing the same problem. Solution is simple but you know finding out the right spot is the difficult task.
I've a service injected into all of my routes and the name of the service is "refresh". When I call refreshModel:true in the route as we all know ember in the backend calls this.refresh() method.
But, here in my case, a service with refresh name is already been injected in the application, ember is not calling this.refresh() method of the route instead calling the injected service which is obviously not a method.
So, it is throwing me a error this.refresh is not a function. Ember would've have given the error more specifically but again its hard for anyone to expect this scenario. Anyways, thanks for all who gave the solutions which directed me in the right path.

subdirectories within ember controller not working

from this post it seems that sub directories within ember controller should work.
https://github.com/ember-cli/ember-cli/issues/1219
however its not working for me .
here is my code branch like (directory cm contains a child directory views):
/controllers/cm/views/item.js
/routes/cm/views/item.js
/templates/cm/views/item.js
when i try to populate the model in route using the code below i see the data but when i put the same code in controller it never gets executed.
model: function(){
return this.store.find('item',{id: "1"});
}
entry in router.js is as follows:
this.resource('cm', {path: '/cm/:id'} , function() {
this.route('views');
this.route('views.items', {path: '/views/items'});
});
Clearly ember is not able to resolve the controller correctly.
Not sure how to fix this ...
That its becuase the model hook in a route works differently than in the controller.
in a route it is a method that can return a promise, the route will wait for the promise to be resolved before setting up the controller.
in the controller, it is just an attribute, which won't get executed until you getit, and even then, all you will get its a promise.
Wat?! Subdirectories work just fine. First, I'm not sure it's the best idea to use views or items as route names, as they're both very generic, and also used in some of the ember internals and can confuse things. Declaring a model called View could very well even break things in your app.
The controller/route/template structures for your router.js will be as follows:
<controllers|routes|templates>/cm.js
<controllers|routes|templates>/cm/index.js
<controllers|routes|templates>/cm/views.js
And I'm not sure what views.items would look like, because this would probably be better suited to making views a resource instead, or using a dash in the name, in which case the route declaration would be this.route('views-items', {path: '/views/items'});
Overall, I think your router definition should look like so:
this.resource('cms', function() {
this.resource('cm', {path: '/:cm_id'}, function() {
this.route('views');
this.route('views-items', { path: '/views/items' });
});
});
This isn't meant to be a quip--I'm here to help--but I think you need to spend a little more time with Ember's routing documentation to understand the conventions that Ember is expecting for certain router definitions. Also, the ember inspector tool is a really great asset when debugging router issues: https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi

Lazy loading route definitions in Ember.js

I'm trying to implement lazy loading in an Ember.js application. Ideally, I'd prefer to have all the relevant code for each module, including any controller and route definitions, in a separate .js file that gets lazy loaded.
Right now, the js file gets loaded correctly when I transition to the route, but because Ember implicitly generates a route definition, the implicitly-generated route object is used instead of the route in my lazy-loaded js file.
In my lazy-loaded js file, I've got a route App.UsersManagerRoute that should be linked to the users.manager route. In the Ember Inspector, I can see that an implicitly generated route is being used instead, even after I've loaded the js file.
To try to fix this, I've tried to manually register the route after loading the js file, but it doesn't seem to be working. This is my code that does the lazy loading:
Ember.Router.reopen({
_doTransition: function (_targetRouteName, models, _queryParams) {
var resourceName = _targetRouteName.split('.')[0];
var self = this;
var transition = self._super(_targetRouteName, models, _queryParams);
transition.abort();
var fullRouteName = 'route:' + camelizeRouteName(_targetRouteName);
self.container.unregister(fullRouteName);
App.lazyLoad(resourceName, function() {
self.container.register(fullRouteName, App[sentenceCasedRouteName(_targetRouteName) + 'Route']);
transition.retry();
});
return transition;
}
});
After I unregister the implicitly generated route and register my lazy-loaded route, the route definition seems to be used correctly, but for some reason, I see a blank page instead of the right template. I'm not too sure what I'm missing here, or if what I'm trying to do is the recommended approach.
All the examples of lazy loading in Ember I've seen so far place the Route outside the lazy-loaded file. Is that the only option that would work?
Auto generation of ember routes is caused by link-to component through href computed property. Never fight against it. Ember will not work properly and you will loose. But you should know it deeply in order to understand the mechanism.
href LinkToComponent method ask for a URL. Before answer, Ember looks for the route. If it doesn't exist, Ember creates one from route:basic.
Container and Registry have some useful method: reset and lookup the former, register and unregister the latter.
register and unregister modify the registry.
lookup creates instances if they don't exist, looking for the factory in factoryCache, and storing them in cache. If the factory doesn't exist there, it asks the Registry.
reset clears cache and factoryCache of the specified member.
That said, the right sequence in order to achieve lazy loading should be:
unregister(fullName);
reset(fullName);
register(fullName, factory);
lookup(fullName);
For an initial solution, have a look at https://github.com/ricottatosta/ember-wiz
Auto generation of ember object is caused by link-to component through href computed property. In order to avoid this behavior (it could be responsible of blank pages) I advice to change href to avoid calling function that calculate so called 'intention' that autogenerate missing objects.

initial route is not in history -- ember.js location: "history"

I'm using ember.js with location: "history". The first route of my site that is loaded (i.e. the one I type into the URL) renders fine. I can click a linkTo anchor to get to a second route, but when I click the back button to return to the first route (the initially loaded one), it is not routed.
Is there something I can do to push that initial route into the history? Should I need to do this?
My route mapping looks like this:
App.Router.reopen({
location: "history"
});
App.Router.map(function() {
this.resource("foods", function(){
this.route("index", {path: "/"});
});
this.route("fourOhFour", { path: "*:"});
});
Note: it doesn't seem to matter whether I begin at http://mysite.example/ or http://mysite.example/foods. In either case, attempting to back onto the initially loaded route has no effect.
I believe that perhaps I should be pushing something into the history but don't know how to do it, nor why I should need to. "fourOhFour" is just my handler for undefined routes, BTW. I don't think it's related to this issue.
Any advice welcome.
Good catch on this one. I just ran into the same issue and started digging around into the Ember.HistoryLocation. I found this commit on github to a fork of ember.js that fixed the problem for me:
https://github.com/teddyzeenny/ember.js/commit/c2c483dc592bb926c210e2c4c174dba7314d18dd
... I actually just merged the diff from this commit to my local copy of ember.js, and am now running history routing just fine for dev, which is good enough to keep me going until this will get wedged back into the main project.

Router v2.1 transitionTo does not work

I'm trying to use the new Router API (at commit 6a165ad), and I have some problems.
Given this router:
Router.map(function(match) {
match("/posts").to("posts", function(match) {
match("/new").to('new', function(match) {
match("/author").to('author');
});
});
});
I'm trying to transition to the new route.
Using new.index: this.transitionTo('new.index')
It works, but as you can see the route name is not really explicit (we don't even know that it's for a new post). It's consequently not a viable solution.
Using posts.new: this.transitionTo('posts.new')
I hoped it works, but an error is thrown:
The route posts.new was not found.
I believed the transition to the index was made automatically, but it seems not.
Using customized route name:
Since the commit specified above, Ember allows custom route naming. As my previous attempt does not work, I tried to force the new route to be posts.new, but it still does not work (idem if it was foo.new).
It looks like its not possible to go to a customized route that has nested routes.
TL;DR
I'd like to transition to the new route (and specifying posts). How should it be done ?
Before the router v2.1, I had routes that has child without to (i.e. match("/posts", function(match) { ... })), is it still working ? If so, what's the name of its children ?
This was actually a bug in Ember. Because index is implicit, you should not need to explicitly provide it.
The bug was fixed on master.
If you want to go to a route that has child routes, you should transitionTo the specified name of the route, and Ember will automatically add the index for you.