ember.js
ember.js copied to clipboard
Infinite loop when aborting query param transition opting in for refreshModel
The title says it all really. Aborting the transition sends the router into an infinite loop, see here:
http://discuss.emberjs.com/t/transition-abort-with-query-params-does-not-abort-transition/8830
JsBin here: http://emberjs.jsbin.com/luzaca/edit?html,js,console,output When you hit 'Go to 2' you should get a call stack exceeded error.
The same thing happens in 2.1. Which is not surprising because the bad code is in router.js - https://github.com/tildeio/router.js/blob/master/lib/router/router.js#L33 .
@francisperp there is a workaround, by using another route hook to abort can you avoid the infinite loop created by the combination of QueryParam change and willTransition use?
- http://guides.emberjs.com/v2.1.0/routing/preventing-and-retrying-transitions/
See this alternative implementation using the beforeModel
hook: http://emberjs.jsbin.com/xobohu/6/edit?js,console,output
@locks This may be a documentation concern in the case where query param + refresh + willTransition + transition.abort
are used an infinite loop is created. This should be avoided by using another hook to abort the transition, e.g. beforeModel
.
@pixelhandler Thanks for the guidance - good to know that it does work there. However the use case I have for this is handling transitions in the willTransition
hook of my application route - willTransition
bubbles up active routes and I can interact with it there. beforeModel
does not bubble, There are many reasons for doing this - implementing any kind of global transition block for example.
I have actually hacked together a solution for my use case, which involved overwriting part of the router prototype. It took me 8 hours, and after spending that much time with the router code it seems to need a deep refactoring right the way through - the cause of the bug is that the code itself is overly stateful and circular, to the point where functions return values that may or may not have been registered to this.activeTransition
after a recursive call. And all abort does is set this.activeTransition
to null
...
Just wondering if this will be addressed as a bug? I don't think I have permission to label it as one!
I am also running into this issue, I think it should be marked a bug.
I've played around trying to find a workaround but the best I've come up with is throwing an error within queryParamsDidChange
. That does abort the transition, but it doesn't seem like the right thing to do.
This is also affecting our app. The use case is we have a parent route with a list of items and some filtering QP's, and a child route that is an edit view. The childroute uses willTransition
to abort the transition if there are unsaved changes.
In our case, we may just refactor away from this design to work around this issue.
This is also causing issues in our app. This should be classified as a bug.
I just stumbled over the same issue when trying to abort a transition using the following query parameter setup:
queryParams:{
param: {
refreshModel: true,
as: 'alias'
}
}
Hower, if all query parameters are at their default states, the call to transition.abort()
works as expected. Is there any resolution planned in the near future?
Just bumped into this issue. Are there any new suggestions on how to handle it?
Got hit by this today also, my use case: need to abort transition + show a confirmation popup on willTransition
if the model is dirty. Any ideas on how to handle this?
I ended up saving a flag on the controller for the target route and then use that to deside whether or not to block the transition in the beforeModel hook of the target route.
The downside is that all of those controllers need to be defined explicitly because otherwise the resolver starts throwing errors.
Ironically the app we work on ran into this bug as well. So we're borrowing from the idea here to work around: https://github.com/emberjs/ember.js/issues/9818#issuecomment-394623779
@chadhietala - Any chance the router.js / router service updates for 3.6 have made this a bit easier to dig into (or possibly even fixed)?
This is an issue in our app as well. I'd consider this a major bug with the ember router and am surprised it has not been addressed after more than 3 years.
@francisperp there is a workaround, by using another route hook to abort can you avoid the infinite loop created by the combination of QueryParam change and willTransition use?
- http://guides.emberjs.com/v2.1.0/routing/preventing-and-retrying-transitions/
See this alternative implementation using the
beforeModel
hook: http://emberjs.jsbin.com/xobohu/6/edit?js,console,output@locks This may be a documentation concern in the case where query param + refresh + willTransition +
transition.abort
are used an infinite loop is created. This should be avoided by using another hook to abort the transition, e.g.beforeModel
.
I was able to successfully work around this bug by calling transition.abort()
in the beforeModel
hook.
Hmm, I just updated to 3.6 (well, 3.7 I guess), and I'm getting some sort of queryParam-related infinite loop where there wasn't one before. Not sure offhand if it's the same issue or just a shared symptom just yet, but something's up.
[EDIT] My own issue turned out to be https://github.com/ember-engines/ember-engines/issues/614 -- probably a red herring after all.
I have the same issue in 2020 with 3.12(LTS).
This is what happens for me when routing from a translation route to another:
In the app I'm working on, all translation routes extend one parent route. Therefore, they all share the same controller and since controllers are singletons, they share the same locale property. So, transitioning from a route with locale 'ES' to another route with locale 'FR', for instance, causes a second transition request by changing the locale queryParam. This second transition gets stuck in the abort<-->retry loop.
This is what I've figured out so far, I might be mistaken though.
Still happening in 4.3.
My workaround—admittedly not great—is to toggle the refreshModel
property to false before aborting the transition, and then back to true.
async willTransition(transition: Transition) {
if (this.controller?.changeset?.isDirty)
// workaround for https://github.com/emberjs/ember.js/issues/12473
this.queryParams.parentId.refreshModel = false;
await transition.abort();
this.queryParams.parentId.refreshModel = true;
}
}
Still happening in 4.4 also.
Toggling the refreshModel
property indeed seems to stop the infinite loop. However, it seems like the query parameters for the current route are being removed when aborting the transition.