ember.js icon indicating copy to clipboard operation
ember.js copied to clipboard

[Bug] <RouterService>#transitionTo incorrectly re-runs the the model hook when query params do not change

Open NullVoxPopuli opened this issue 3 years ago • 13 comments

🐞 Describe the Bug

  • have queryParams
  • configure the query params to refeshModel: true
  • navigate to a child route with the router service's transitionTo
  • notice that the parent route's model hook re-runs

🔬 Minimal Reproduction

Twiddle

😕 Actual Behavior

the parent model hook is re-running (in the application route in the repro)

🤔 Expected Behavior

the parent model hook should not run (as with the transitionToRoute behavior)

🌍 Environment

  • Ember: - Octane+
  • Node.js/npm: - n/a
  • OS: - n/a
  • Browser: - n/a

NullVoxPopuli avatar Apr 16 '21 17:04 NullVoxPopuli

I came across a behavior which may be related to this bug. The context is as follows:

parent route -- child route ---- component

The parent route's controller has a queryParam. The component needs to update that queryParam and uses this.router.transitionTo({ queryParams: { prop: value }}); to do so. The queryParam prop is being modified, which is different than this bug report, but the child route model hook is still being triggered.

To work around the issue I now call this.transitionToRoute({ queryParams: { prop: value }}) on the child route's controller. The model hook is no longer run again in this case.

trevordevore avatar Apr 17 '21 20:04 trevordevore

I'm running into this issue as well. Seems to be happening when migrating to the new class syntax.

btecu avatar Apr 26 '21 18:04 btecu

We actually had this come up. I accidentally use this as a behavior to refresh a route without realizing this was going on until I called it twice... 🤦🏽

This is documented in the transitionTo behavior but would be nice to not have default queryParam values pop up.

rtablada avatar Jun 04 '21 19:06 rtablada

This is one of the aged issues https://github.com/emberjs/ember.js/issues/16349

ro0gr avatar Jun 05 '21 12:06 ro0gr

I think I came across the same issue while migrating to ember 3.24 with native class syntax:

parent route
-- child route
----- component

The component was using the router service to update query params of the child route:

this.router.transitionTo({ queryParams: {} })

Or even simply the route:

this.router.transitionTo(newRoute)

But the parent route model's hook was re-run.

Delegating the update to the child route's controller using transitionToRoute solved this issue.

panthony avatar Dec 16 '21 13:12 panthony

We're also running into this issue when refactoring the deprecated this.transitionToRoute call in Controllers to this.router.transitionTo.

As this issue causes a lot of extra unnecessary model calls and slows down our app it's a critical issue.

A temporary workaround seems to be returning the previous model state like so:

model(params, transition) {
  super.model(...arguments);

  // Reuse the previous model state when redirecting to, or redirected back from a child route
  if (isRedirectFromOrToChildRoute(transition)) {
    return this.modelFor(this.routeName);
  }

  // Redacted ...
}

// With isRedirectFromOrToChildRoute e.g.
isRedirectFromOrToChildRoute(transition) {
  const routeNameFromStripped = transition.from?.name?.replace('.index', ''); // Can be undefined when it's the first page accessed
  if (routeNameFromStripped) {
    const routeNameToStripped = transition.to.name.replace('.index', '');
    const isChildRoute = routeNameFromStripped.startsWith(routeNameToStripped);
    const isParentRoute = routeNameToStripped.startsWith(routeNameFromStripped);
    const isSameRoute = routeNameFromStripped === routeNameToStripped;

    return !isSameRoute && (isChildRoute || isParentRoute);
  }

  return false;
}

But as it's such a core functionality of routing this seems like a hacky approach ...

IgnaceMaes avatar Jul 08 '22 13:07 IgnaceMaes

I'm experiencing the same issue on ember 4.6.0

I've confirmed that if I remove the refreshModel: true from the queryParam the parent hook doesn't fire on transition.

abueloshika avatar Oct 12 '22 12:10 abueloshika

Also experiencing this issue on Ember 3.28.11, Ember 4.4.4 and Ember 4.9.2

Having to stick with Controller.transitionToRoute for certain calls to avoid slow page transitions

Techn1x avatar Dec 21 '22 09:12 Techn1x

I have confirmed the router.transitionTo problem still exists with Ember 4.12

This is now actually a problem as transitionToRoute is removed in ember 5, and I would like to update..

Techn1x avatar Nov 16 '23 09:11 Techn1x

This seems like it may be related to #16349, #20038 and #20512 as well and indeed still occurs in ember 5.

nickschot avatar Feb 29 '24 14:02 nickschot