emberjs / ember.js

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

[Bug] QueryParams get erroneously set when entering transition while there's an ongoing transition #20139

Open sergiofenoll opened 2 years ago

sergiofenoll commented 2 years ago

🐞 Describe the Bug

I'm encountering some strange behaviour related to queryParams when starting a new transition while an ongoing transition is still loading. Routes child-a and child-b both have the same queryParams. When child-a has its queryParams set and is mid-transition (because its model hook hasn't resolved yet), if you then navigate to child-b, the second route will have its queryParams erroneously populated. If you instead wait until child-a's model hook has resolved before navigating to child-b, the queryParams won't get populated (as expected).

🔬 Minimal Reproduction

Repro repo: https://github.com/sergiofenoll/weird-qps

Repo is using v3.28.9, but I also tried with 4.4.2 and I encounter the same behaviour.

😕 Actual Behavior

The query parameters of child-b have been populated.

🤔 Expected Behavior

The query parameters of child-b shouldn't be populated, as they were never set to do so.

🌍 Environment

➕ Additional Context

N/A

ValenberghsSven commented 2 years ago

A real life situation we have going on right now is that we have a sort queryParam on some sibling routes. We have route A: queries a model foo with sort QP for model Foo (async) route B: queries a model bar with sort QP for model Bar

On transitioning from route A to route B while model A is not yet loaded like in the example above results in errors, because sort for model Foo is being applied to model bar. The model hook

In debugging/preventing those errors, I found that adding @query={{hash sort='defaultSortForModelB'}} to the LinkTo of route B resolves the error, this seems to win over the populated queryparams from route A.

ValenberghsSven commented 2 years ago

Another workaround could be to have unique queryParams per route. If we use the example and change the QP of route-b to foo2 and bar2, the QP of route-a no longer match and can't populate those of route-b.