Skip to content

fix(router): support lazy loading for named outlets#32688

Closed
asvishnyakov wants to merge 3 commits intoangular:masterfrom
asvishnyakov:master
Closed

fix(router): support lazy loading for named outlets#32688
asvishnyakov wants to merge 3 commits intoangular:masterfrom
asvishnyakov:master

Conversation

@asvishnyakov
Copy link
Copy Markdown

@asvishnyakov asvishnyakov commented Sep 15, 2019

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

This is correct implementation and replacement of #25483

This PR is avoid problem appear in #25483: the same error occurs when you have lazy-loaded default route and routes with empty path and named outlet before it.


Given the following route configuration:

[
    {path: '', loadChildren: 'children'},
    {path: 'a', loadChildren: 'otherChildren', outlet: 'aux'}
]

With this configuration, using the outlet as an entry point to the application, the root module will not load properly and results in the following error:

TypeError: Cannot read property 'routes' of undefined at getChildConfig (router.js:3041)

The _loadedConfig property of the route remains undefined as the expandSegmentAgainstRoute() isn't executed.

This issue is only present if the root has a lazy loaded module, works fine with a component or even with a lazy loaded module if the root path is not empty.

Issue Number: #12842

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@asvishnyakov asvishnyakov requested review from a team September 15, 2019 19:35
@asvishnyakov
Copy link
Copy Markdown
Author

Also, possible fix #10981
@Jonathan002 FYI
@jasonaden May you review?

@ngbot ngbot bot added this to the needsTriage milestone Sep 16, 2019
@asvishnyakov
Copy link
Copy Markdown
Author

Any update?

@Flyrell
Copy link
Copy Markdown

Flyrell commented Jan 3, 2020

@asvishnyakov Thank you for this, I hope Angular team will take their time to review those few lines of code before v9 is released (although, it might be too much to ask).

Anyways, there are some indentation issues in packages/router/src/apply_redirects.ts which might make things go a bit slower to accept and merge.

@dustintheweb
Copy link
Copy Markdown

This is still not working fully & #10981 (comment) is locked for some reason. Plz halp.

@pullapprove pullapprove bot requested a review from atscott March 24, 2020 17:15
@khiami
Copy link
Copy Markdown

khiami commented Jul 25, 2020

Any updates on this ticket?

In general, the router only matches and loads a single config tree. However,
named outlets with empty paths are a special case where the router can
and should actually match two different `Route`s and ensure that the
modules are loaded for each match.

This change updates the "ApplyRedirects" stage to ensure that named
outlets with empty paths finish loading their configs before proceeding
to the next stage in the routing pipe. This is necessary because if the
named outlet has `loadChildren` but the associated lazy config is not loaded
before following stages attempt to match and activate relevant `Route`s,
an error will occur.

fixes angular#12842
@googlebot

This comment has been minimized.

@googlebot googlebot added cla: no and removed cla: yes labels Aug 4, 2020
@atscott atscott removed the request for review from a team August 4, 2020 22:17
@atscott
Copy link
Copy Markdown
Contributor

atscott commented Aug 5, 2020

  • Rebased PR
  • reverted .gitignore changes
  • Updated routes.map to use try...catch and throwError to ensure possible errors thrown from expandSegmentAgainstRoute are handled by catchError code
  • Updated test to more accurately reflect the use-case in the issue report and so that it would fail without the changes in apply_redirects

The internal tests have quite a few failures so this will require further investigation into why this change breaks them.

@atscott
Copy link
Copy Markdown
Contributor

atscott commented Aug 5, 2020

@googlebot I consent

@googlebot
Copy link
Copy Markdown

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@atscott
Copy link
Copy Markdown
Contributor

atscott commented Aug 6, 2020

I reviewed one of the failing tests and found that it fails because this finds all configs which match the url tree and loads each one if they have lazy children. The previous behavior would find and load only the first match. Generally, this would be fine because the router usually only activates a single config. Matches that appear earlier in the config take precedence (which is working as intended and documented). The failing provides an override to the real route so that it loads a no-op module. This change makes it so that the test override and the real Route match and are loaded, resulting in the failure.

i.e.

const REAL_ROUTES = [
  {
    path: 'b/c',
    loadChildren: 'xyz',
    pathMatch: 'full'
  },
];
=====

...
{
  testRoutes: [
  routes: [
    {path: 'a/b/c', loadChildren: 'noop_module'},
    {path: 'a', children: REAL_ROUTES},
  ],
}

In our case with these empty path named outlets, we have to load matched configs from each outlet. This approach also presents a problem because it will always load wildcard routes, which will always match the given url tree. At the moment, I can't really think of a solution to this. If no backwards compatible solution can be found, we could provide this as opt-in behavior in ExtraOptions, something like lazyRouteLoadingBehavior: 'firstMatch'|'allMatches'

Edit:
Pushed another fixup commit with a test demonstrating the failure described above

@atscott atscott added the action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews label Aug 6, 2020
@atscott
Copy link
Copy Markdown
Contributor

atscott commented Aug 7, 2020

Closing in favor of #38379, as that one addresses the issues mentioned in #32688 (comment)

@atscott atscott closed this Aug 7, 2020
@angular-automatic-lock-bot
Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 7, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews area: router cla: yes hotlist: devrel

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants