Skip to content

Document that CanReuse must be implemented on parent routes for sub-route reuse to work #83

@insinfo

Description

@insinfo

Currently, the AngularDart router’s CanReuse hook works as expected when you implement it on a component whose route is being reactivated. However, if that component is rendered inside a parent route (i.e. as a sub-route), its own CanReuse implementation won’t be consulted unless the parent also implements CanReuse and returns true. This subtle requirement is not mentioned in the public docs, leading to confusion when developers find that their sub-route’s canReuse() is never called.

What’s Missing

The Routing Guide does not explain that:

  • A sub-route’s CanReuse.canReuse(oldState, newState) will only be invoked if its parent component’s -
  • CanReuse.canReuse(...) also returns true.

Therefore, to enable reuse logic for a child outlet, the parent component must itself implement CanReuse and allow reuse for the relevant state transitions.


Reproduction Steps

  1. Create a parent component (ParentComponent) with a <router-outlet> for child routes.
  2. Create a child component (ChildComponent) that implements CanReuse and logs or returns false in its canReuse() method.
  3. Navigate from one sibling route to another (e.g. /parent/childA/parent/childB).
  4. Observe that ChildComponent.canReuse() is not called, even though ChildComponent implements CanReuse.

Expected Behavior

When navigating between child routes under the same parent, the child’s CanReuse.canReuse() should always be invoked to decide reuse or destruction of the component instance—regardless of whether the parent implements CanReuse.


Actual Behavior

AngularDart currently skips the child’s canReuse() call if the parent does not implement CanReuse or returns false. This is by design (due to hierarchical activation logic), but it isn’t documented anywhere in the official guide.


Proposed Documentation Update

Under the Route Lifecycle or CanReuse section in the Routing Guide:

  1. Explain the hierarchical reuse check:

    “Note: The router traverses outlets from the root down. It will only call a component’s canReuse() if all of its ancestor outlets also agree to reuse. That means any parent component hosting a <router-outlet> for this route must itself implement CanReuse (and return true) in order for the child’s canReuse() to be evaluated.”

  2. Add a small code example:

@Component(
  selector: 'parent-comp',
  template: '<router-outlet></router-outlet>',
)
class ParentComponent implements CanReuse {
  @override
  Future<bool> canReuse(RouterState oldState, RouterState newState) async {
    // allow reuse whenever the parent’s path params haven’t changed
    return oldState.parameters['id'] == newState.parameters['id'];
  }
}

@Component(
  selector: 'child-comp',
  template: '<p>Child content</p>',
)
class ChildComponent implements CanReuse {
  @override
  Future<bool> canReuse(RouterState oldState, RouterState newState) async {
    // decide reuse based on child-specific logic
    return true;
  }
}

Thank you for considering this enhancement—adding these details will help developers avoid unexpected behavior and fully leverage the CanReuse lifecycle hook in nested routing scenarios.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions