question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot use Enum in Route's field 'loadChildren'

See original GitHub issue

I’m submitting a…


[x] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:

Current behavior

If you create a route which contains enum value in ‘loadChildren’ field.

const enum TestEnum {
  item = 'app/customers/customers.module#CustomersModule'
}

const routes: Routes = [
  {
    path: 'customers',
    loadChildren: TestEnum.item,
  },
...

then you get error when you try to open a page with lazy load module.

ERROR
Error: Uncaught (in promise): Error: Cannot find 'CustomersModule' in 'app/customers/customers.module'
Error: Cannot find 'CustomersModule' in 'app/customers/customers.module

Expected behavior

Expected that lazy loaded module is loaded if Enam is used as a value of loadChildren property.

Minimal reproduction of the problem with instructions

stackblitz: https://stackblitz.com/github/VlasovSergey/lazy-loading-ngmodules-issue-repro?file=src%2Fapp%2Fapp-routing.module.ts github: https://github.com/VlasovSergey/lazy-loading-ngmodules-issue-repro

  1. Run ng serve
  2. Open application
  3. Press Custumers button to see the error.

What is the motivation / use case for changing the behavior?

We used enums in ‘loadChildren’ field on Angular 5.2.10 and it worked properly.

Environment


Angular version: 6.1.6


Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
trotylcommented, Sep 6, 2018

Your reproduction is not an Angular issue nor relates to enum, try any variable in loadChildren and it will fail: https://stackblitz.com/edit/angular-ibhrmk-gh4px4?file=src/app/app-routing.module.ts

StackBlitz cheats the lazy-module with replacing string literal to module imports at build time:

routes = [
  {
    path: 'customers',
    loadChildren: tmp,
  },
  {
    path: 'orders',
    loadChildren: function () { return orders_module_1.OrdersModule; }
  },
];

This process is not controlled by Angular, but StackBlitz backend build tools.

For a valid reproduction you can create a new Angular CLI project and copy the code there, then share the repo.

1reaction
alxhubcommented, Nov 30, 2018

I stepped through the compiler this morning and tracked this down.

Sometime between Angular 5 and now, we modified ngc to “lower” the loadChildren expression. Thus, an expression of:

RouterModule.forRoot([{path: '', loadChildren: () => SomeModuleFactory}])

Became:

export const ɵa = () => SomeModuleFactory;

...

RouterModule.forRoot([{path: '', loadChildren: ɵa}])

This had the effect of enabling lambda expressions in loadChildren, an oft-requested Angular feature.

However, this had a side effect of also lowering any other non-primitive expression, such as a reference to an enum value. Once lowered, the compiler can only see the ɵa dynamic reference and is not able to correctly discover the route behind it.

Given the limited scope of this regression, the fact that rolling back the change would introduce a much larger breakage of users now relying on lowered loadChildren functions, the work which would be required to differentiate between the two cases and correctly support both lowering functions and not lowering enums, it’s unlikely we will be able to fix this before Ivy. This issue is, however, fixed in the Ivy compiler, which does not require the lowering functionality at all.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Cannot use enum in Angular Routes - Stack Overflow
This works perfectly fine with ng serve and compiled code without aot enabled. However, with production code or with aot enabled it always ......
Read more >
Handbook - Enums - TypeScript
Enums allow a developer to define a set of named constants. Using enums can make it easier to document intent, or create a...
Read more >
angular/angular - Gitter
Unhandled Promise rejection: Cannot read property 'moduleType' of undefined ... bootstrap table in Angular 7.2 project however it does not use any styles....
Read more >
@getbeyond/ng-beyond-js - npm
Run build.sh and make sure it builds without errors;; Squash merge - the commit message should have version number in the first line;;...
Read more >
Angular Basics: Working With Enums in Angular - Telerik
const enums can't have computed members since no extra code is generated for computing the values of the enums at compile time. Use...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found