emberjs / ember.js

Ember.js - A JavaScript framework for creating ambitious web applications
https://emberjs.com
MIT License
22.46k stars 4.21k forks source link

[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 1 month ago

mkszepp commented 1 month ago

🐞 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

βž• 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 commented 3 weeks ago

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

mkszepp commented 3 weeks ago

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

kategengler commented 3 weeks ago

@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 commented 3 weeks ago

@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 commented 3 weeks ago

'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 commented 3 weeks ago

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)