Skip to content

Creating ROUTES with custom factory function ends up with "Cannot read property 'loadChildren' of undefined" error #22700

Closed

Description

@jtomaszewski

I'm submitting a...

[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  <!-- Please search GitHub for a similar issue or PR before submitting -->
[ ] 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

Current behavior

When angular compiler finds a provider that defines ROUTES, but which doesn't have a useValue property, (because it has f.e. useFactory property instead) it fails with the following error:

ERROR in TypeError: Cannot read property 'loadChildren' of undefined
    at _collectLoadChildren (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@angular/compiler/bundles/compiler.umd.js:29034:20)
    at listLazyRoutes (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@angular/compiler/bundles/compiler.umd.js:29009:49)
    at AotCompiler.listLazyRoutes (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@angular/compiler/bundles/compiler.umd.js:31150:51)
    at AngularCompilerProgram.listLazyRoutes (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@angular/compiler-cli/src/transformers/program.js:156:30)
    at AngularCompilerPlugin._listLazyRoutesFromProgram (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:304:38)
    at Promise.resolve.then.then (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:583:50)
    at process._tickCallback (internal/process/next_tick.js:109:7)
webpack: Failed to compile.

Expected behavior

Defining a provider for ROUTES with other providers like f.e. FactoryProvider should just work.

Minimal reproduction of the problem with instructions

  1. Write your module like this:
import { NgModule, NgModuleFactory, Compiler } from '@angular/core';
import { Routes, RouterModule, ROUTES } from '@angular/router';

export function MainRoutingLazyRoutesFactory(compiler: Compiler): Routes {
  return [
    {
      path: 'dashboard',
      loadChildren: () => {
        return <any>System.import('../features/dashboard/dashboard.module')
          .then(({ DashboardFeatureModule }) => DashboardFeatureModule)
          .then(ngModule => {
            if (ngModule instanceof NgModuleFactory) {
              return ngModule;
            } else {
              return compiler.compileModuleAsync(ngModule);
            }
          });
      },
    },
  ];
}

@NgModule({
  imports: [RouterModule],
  exports: [RouterModule],
  providers: [
    {
      provide: ROUTES,
      multi: true,
      deps: [Compiler],
      useFactory: MainRoutingLazyRoutesFactory,
    },
  ],
})
export class MainRoutingModule {}
  1. Try to compile it, in either JiT or AoT mode.

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

It lets you to easily implement lazy loaded modules in your routes with your custom way.

Environment

node 6.11.5
npm 5.6.0
angular 5.2.8
@ngtools/webpack 1.10.2

Activity

  1. added this to the needsTriage milestone on Mar 10, 2018
  2. jtomaszewski commented on Mar 10, 2018

    @jtomaszewski
    Author

    I've followed through the stack trace and think I've found what causes the bug:

    I think it's because of this code in the angular/compiler's source:

    function listLazyRoutes(moduleMeta, reflector) {
        var /** @type {?} */ allLazyRoutes = [];
        for (var _i = 0, _a = moduleMeta.transitiveModule.providers; _i < _a.length; _i++) {
            var _b = _a[_i], provider = _b.provider, module = _b.module;
            if (tokenReference(provider.token) === reflector.ROUTES) {
                var /** @type {?} */ loadChildren = _collectLoadChildren(provider.useValue);
                for (var _c = 0, loadChildren_1 = loadChildren; _c < loadChildren_1.length; _c++) {
                    var route = loadChildren_1[_c];
                    allLazyRoutes.push(parseLazyRoute(route, reflector, module.reference));
                }
            }
        }
        return allLazyRoutes;
    }
    

    According to the stacktrace, it fails on _collectLoadChildren(provider.useValue);.

    Obviously, this provider has no useValue. IMHO we should skip parsing it, if it doesn't have such a property.

    P.S. We've submitted this issue on angular-cli first ( angular/angular-cli#9913 ) but they redirected us here.

    P.S.2. In the meantime, we've managed to build a workaround to make it compile anyway:

    export const MainRoutingLazyRoutesFactoryProvider: FactoryProvider = <any>{
      provide: ROUTES,
      multi: true,
      deps: [Compiler],
      useFactory: MainRoutingLazyRoutesFactory,
      useValue: [],
    };
    delete (<any>rtMainRoutingLazyRoutesFactoryProvider).useValue;
  3. jasonaden commented on Mar 16, 2018

    @jasonaden
    Contributor

    @jtomaszewski Thanks for the issue. I would like to help dig into this a little bit as it's something I think many people want. However, can you please provide a running example of your code? Both the working and not working version using StackBlitz?

  4. emanuelpinho commented on Apr 10, 2018

    @emanuelpinho

    @jasonaden I am getting the same error but with a different case scenario. I don't know if this is related with angular or webpack cli.

    My issue seems to be related with using an object initializer in a route object. Here an example code https://stackblitz.com/edit/angular-nxvknf. I am using a 'test' key inside app routes and seems like it is working using stackblitz.

    When using webpack to compile, it is not working. It is calling _collectLoadChildren with provider.useValue, that is undefined in this case.
    If i switch the data property to a string, it works.
    Another strange thing is that it only happens when it compiles the first time. If i save with live reloading it is compiled successfully.

    Do you think that they could be related?

  5. added
    area: coreIssues related to the framework runtime
    and removed on Apr 10, 2018
  6. jtomaszewski commented on Apr 14, 2018

    @jtomaszewski
    Author

    @jasonaden Sure, here it is: https://stackblitz.com/edit/angular-db84dh .

    Strangely it works okay in stackblitz, but don't let it mislead you.

    When you download the code on your computer and run npm install && ng serve manually, then it will return the error in the console:

    image

  7. modified the milestones: needsTriage, Backlog on May 3, 2018
  8. doivosevic commented on May 8, 2018

    @doivosevic

    For me it consistently fails on run of ng serve but every next recompilation (on file save) is successful.

  9. 15 remaining items

  10. removed
    P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
    on Oct 1, 2020
  11. modified the milestones: Backlog, needsTriage on Oct 1, 2020
  12. added
    P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
    on Oct 1, 2020
  13. modified the milestones: needsTriage, Backlog on Oct 1, 2020
  14. added
    P5The team acknowledges the request but does not plan to address it, it remains open for discussion
    needs: clarificationThis issue needs additional clarification from the reporter before the team can investigate.
    and removed
    P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
    on Oct 1, 2020
  15. JoostK commented on Sep 30, 2021

    @JoostK
    Member

    This was a ViewEngine bug and listLazyRoutes was removed in #43591.

  16. angular-automatic-lock-bot commented on Oct 31, 2021

    @angular-automatic-lock-bot

    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.

  17. locked and limited conversation to collaborators on Oct 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P5The team acknowledges the request but does not plan to address it, it remains open for discussionarea: coreIssues related to the framework runtimefreq1: lowneeds: clarificationThis issue needs additional clarification from the reporter before the team can investigate.type: bug/fix

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions