Skip to content

fix(lazyLoad): abort URL-sourced transition when its target was replaced by the lazy load#2

Closed
simshanith wants to merge 1 commit into
masterfrom
fix/lazyload-stale-target-abort
Closed

fix(lazyLoad): abort URL-sourced transition when its target was replaced by the lazy load#2
simshanith wants to merge 1 commit into
masterfrom
fix/lazyload-stale-target-abort

Conversation

@simshanith

@simshanith simshanith commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

Alternative (stricter) fix for ui-router#850 — companion to the unconditional-abort PR #1; pick one.

Same bug: when a URL matches a future state's prefix but nothing in the lazy-loaded module matches the full URL, the original URL-sourced transition resumed after urlService.sync() and activated the already-deregistered .** placeholder, superseding the otherwise() transition started by sync().

Fix

In retryTransition() (src/hooks/lazyLoad.ts), after delegating to sync(), abort the original transition only if its target state is no longer in the registry (i.e. the lazy load replaced the .** placeholder). If the target somehow survives the lazy load (e.g. the module registered unrelated states), existing fall-through behavior is preserved.

Trade-off vs the primary fix

  • Primary (return false unconditionally): simpler; any URL-sourced transition that falls through to sync() is aborted — sync() re-derives the correct destination either way.
  • This PR (conditional): narrower behavior change; only aborts when the transition demonstrably targets a deregistered state.

Tests

Same two regression tests as the primary PR (both fail on master, pass here):

  • deep-linking to a URL that prefix-matches a .** future state but matches nothing in the loaded module activates the otherwise() rule's state
  • the original transition to the deregistered placeholder is rejected with RejectType.ABORTED

Full suite: 587/590 pass (3 pre-existing skips), same as master baseline.

Closes ui-router#850

…ced by the lazy load

When a URL matches a future state's prefix but nothing in the lazy
loaded module matches the full URL, retryTransition() delegates to
urlService.sync() but returned undefined, letting the original
transition resume and activate the deregistered .** placeholder,
superseding the otherwise() transition started by sync().

After delegating to sync(), check whether the original transition's
target state is still registered; if the lazy load replaced it
(e.g. a .** placeholder), abort the original transition so the
sync()-initiated transition (e.g. the otherwise() rule) can complete.

Closes ui-router#850
@simshanith

Copy link
Copy Markdown
Owner Author

closing in favor of #1 / ui-router#851

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

lazyLoad: URL-sourced transition to a replaced .** placeholder supersedes the otherwise() transition started by sync()

1 participant