Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Transition to same route without parameters creates error Uncaught TypeError: routeInfos[(routeInfoLength - 1)] is undefined when a queryParam has default value null #20701

Open
mkszepp opened this issue May 24, 2024 · 7 comments

Comments

@mkszepp
Copy link
Contributor

mkszepp commented May 24, 2024

🐞 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.

grafik

🔬 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'];
}
  1. Run ember s
  2. Page is loading and will be auto redirected to sub route "base" (no error)
  3. Refresh page (F5)
  4. 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

@kategengler
Copy link
Member

If on the route you change from this.router.transitionTo to this.transitionTo, does it work?

@mkszepp
Copy link
Contributor Author

mkszepp commented Jun 6, 2024

@kategengler this.transitionTo without router doesn't exists 😊. i think it was removed with ember v5 or?

@kategengler
Copy link
Member

@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(...

@mkszepp
Copy link
Contributor Author

mkszepp commented Jun 7, 2024

@kategengler yes this works without any error in js, but router:main is private API, so we are getting this lint error

grafik

When using getOwner(this).lookup('router:application').transitionTo('base'); i'm getting error undefined.

grafik

@kategengler
Copy link
Member

'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.

@mkszepp
Copy link
Contributor Author

mkszepp commented Jun 7, 2024

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)

@johanrd
Copy link
Contributor

johanrd commented Nov 2, 2024

For info, the stack trace leads to this method:

_queryParamsFor(routeInfos: InternalRouteInfo<Route>[]) {
let routeInfoLength = routeInfos.length;
let leafRouteName = routeInfos[routeInfoLength - 1]!.name;
let cached = this._qpCache[leafRouteName];
if (cached !== undefined) {
return cached;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants