[Bug] Transition to same route without parameters creates error `Uncaught TypeError: routeInfos[(routeInfoLength - 1)] is undefined` when a `queryParam` has default value `null`
🐞 Describe the Bug
When adding a transitionTo on higher router we get error Uncaught TypeError: routeInfos[(routeInfoLength - 1)] is undefined.
The error occures, when the default value from queryParameter is null.
🔬 Minimal Reproduction
Example repo: https://github.com/mkszepp/ember-transition-bug
Create a new app with route named base and copy this code parts.
// routes/application.js
import Route from '@ember/routing/route';
import { service } from '@ember/service';
export default class ApplicationRoute extends Route {
@service router;
redirect() {
super.redirect(...arguments);
this.router.transitionTo('base');
}
}
// controllers/base.js
import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';
export default class BaseController extends Controller {
@tracked messageType = null;
queryParams = ['messageType'];
}
- Run ember s
- Page is loading and will be auto redirected to sub route "base" (no error)
- Refresh page (F5)
- Error Uncaught TypeError: routeInfos[(routeInfoLength - 1)] is undefined
It seems like router has problem with default value null, when the current route is the same.
🌍 Environment
- Ember:
v5.8.0(its also present in older versions) - Node.js/npm:
v18.19
➕ Additional Context
There is reported the same error in other cases with older versions. https://github.com/emberjs/ember.js/issues?q=is%3Aissue+is%3Aopen+routeInfos%5B%28routeInfoLength+-+1%29%5D
If on the route you change from this.router.transitionTo to this.transitionTo, does it work?
@kategengler this.transitionTo without router doesn't exists 😊. i think it was removed with ember v5 or?
@mkszepp Sorry forgot we did the one on Route too ... Try using the one off of router (not the same as RouterService) https://api.emberjs.com/ember/5.9/classes/EmberRouter/methods/transitionTo?anchor=transitionTo to see if the behavior is better -- you can get at it with getOwner(this).lookup('router:main').transitionTo(...
@kategengler yes this works without any error in js, but router:main is private API, so we are getting this lint error
When using getOwner(this).lookup('router:application').transitionTo('base'); i'm getting error undefined.
'router:application' isn't a thing afaik, so that explains the undefined. router:main is definitely a private API -- I wanted you to try it for debugging purposes, but you could put it in your app if you wanted.
You can also make your error go away with:
redirect(_, transition ) {
super.redirect(...arguments);
if (transition.to.name !== 'base') {
this.router.transitionTo('base');
}
}
As the problem is trying to redirect into the same route you're already entering.
Yes, checking if user is already on same route works and is fixing the problem, but if you want to reset all query paramenters on start you can't do it (i think we were doing for that)
For info, the stack trace leads to this method: https://github.com/emberjs/ember.js/blob/cca69654f5f23251919c454507465ec2792c642c/packages/%40ember/routing/router.ts#L1146-L1152