Skip to content

Dynamic Routing with AOT #5754

Closed
Closed

Description

@sam-rusty

I'm working on a app where i need to have a logic in routing to decide which page should be the home page, it works fine with JIT but with AOT. Here is how my code looks like

       let subdomain = environment.production ? window.location.host.replace('www.', '').split('.')[0] : 'sahiwal';
       let districts = {sahiwal:'121', faisalabad:'122'}
        export const routes: Routes = [
            {
                path: '',
                component: MasterComponent,
                children: [
                    {
                        path: districts[subdomain] ? '' : 'home',
                        loadChildren: './home.module#HomeModule',
                        data: {title: 'سجاگ'}
                    }, {
                        path: subdomain === domain ? '' : 'main',
                        loadChildren: './main.page.module#MainPageModule',
                        data: {title: 'سجاگ'}
                    },
                    {
                        path: 'news',
                        loadChildren: './news.module#NewsModule',
                        data: {title: 'خبر سجاگ'}
                    }, {
                        path: subdomain === 'features' ? '' : 'features',
                        loadChildren: './archive.module#ArchiveModule',
                        data: {title: 'خبر سجاگ'}
                    }
            }
        ];

Versions

@angular/cli: 1.0.0
node: 6.9.1
os: darwin x64
@angular/common: 4.0.1
@angular/compiler: 4.0.1
@angular/animations: 4.0.1
@angular/core: 4.0.1
@angular/forms: 4.0.1
@angular/http: 4.0.1
@angular/platform-browser: 4.0.1
@angular/platform-browser-dynamic: 4.0.1
@angular/platform-server: 4.0.1
@angular/router: 4.0.1
@angular/cli: 1.0.0
@angular/compiler-cli: 4.0.1

Activity

  1. deebloo commented on Mar 30, 2017

    @deebloo
    Contributor

    For AOT your routes need to be statically analyzable. I'd your need dynamic values in your routes can you use route params instead?

  2. sam-rusty commented on Mar 30, 2017

    @sam-rusty
    Author

    Thanks @deebloo, if you look at my example code i'm getting subdomain from the url and then in routes loading relevant lazy module. somehow i need to do this in routes.
    its a funny question but let me ask you, is there not any way to compile only routes with JIT and all other in AOT? I don't think its possible but let me know what you think?

  3. deebloo commented on Mar 30, 2017

    @deebloo
    Contributor

    You can't do that in the routes. It looks like the only concern here is the actual name of the routes? and no it is not possible

  4. sam-rusty commented on Mar 31, 2017

    @sam-rusty
    Author

    Okay thank you so much @deebloo, i'm gonna close this issue.

  5. hheexx commented on Apr 4, 2017

    @hheexx

    I am having the same problem.

    I save routes in my format that I need because of route localization.
    Then I have a function that translates my format to the array of routes router understands.

    Looks it can't work with AOT like that.

    Any workaround?

  6. crizstian commented on Apr 11, 2017

    @crizstian

    @iridiumsoft

    Does lazy loading working well for you ?

    how is your configuration i am having problems with lazy loading

  7. markoddi commented on Apr 13, 2017

    @markoddi

    I cant get my routes working in AOT either. Works fine in JIT with ng serve

  8. markoddi commented on Apr 13, 2017

    @markoddi

    These are my routes that only don't work in AOT:

    import { Route} from '@angular/router';
    import { HomeComponent } from './home.component';

    export const HomeRoutes: Route[] = [
    {
    path: '',
    component: HomeComponent
    },
    {
    path: 'home',
    component: HomeComponent
    }
    ];

  9. yy7054wyq5 commented on Jun 14, 2017

    @yy7054wyq5

    So if use dynamic routes must close AOT...

  10. lpikora commented on Jun 21, 2017

    @lpikora

    This can be solved by providing routes definition to ROUTES using function factory... (tested on Angular 4.1.2)

    Modify your AppModule (app.module.ts):

    change RouterModul.forRoot in imports array

    imports: [
    RouterModule.forRoot(routes)
    ...
    

    to

    RouterModule.forRoot([])
    

    add this two providers in providers array:

    ... ANALYZE_FOR_ENTRY_COMPONENTS
    } from '@angular/core';
    ...  ROUTES,
    } from '@angular/router';
    ...
    providers: [
    {provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: routes},
    {provide: ROUTES, multi: true, useFactory: getRoutes},
    ...
    

    define factory function (at top of the app.module.ts file):

    export function getRoutes() {
      return routes;
    }
    

    maybe you need also create new file eg: app.routes.ts and put your routes definitions there

    export const routes: Routes = [
                {
                    path: '',
    ...
    

    and import it in AppModule (app.module.ts).

    import { routes } from './app.routes';
    
  11. DanielKucal commented on Aug 15, 2017

    @DanielKucal

    Similar problem here... I have dynamic yet synchronous routes that have to be possible to turn off in config file. I couldn't filter them right in definition due to "function calls are not supported" error and I finally did it in my module constructor by operating on router.config... The routes are added properly and work in JiT and I think they was also working in AoT last time, but now they do not. Any workaround or better solution to make it work in AoT compilation?

    Edit: My problem was caused by code minification, not strictly by AoT compiler. I compared component names to find specific route and it found other one with the same name in AoT. After fixing that, my dynamically filtered routes work as expected.

  12. raujonas commented on Jun 21, 2018

    @raujonas

    @DanielKucal What do you mean by you found another route with the same name in AoT? Can you please explain this to me? I have the same problem, dynamic routes from file are throwing an exception .. Thank you for you help!

  13. DanielKucal commented on Jul 2, 2018

    @DanielKucal

    @raujonas, if I remember that correctly I was comparing class names (which are being replaced during minification). The solution was to add a static field to classes and compare it while matching the routes instead.

  14. liujingbreak commented on Nov 14, 2018

    @liujingbreak

    Bad news in 2018, {provide: ROUTES, multi: true, useFactory: getRoutes} does not work today.

    fix(compiler-cli): ngtools should accept useFactory (lazy routes)

  15. lpikora commented on Nov 14, 2018

    @lpikora

    Solution for Angular 6+

    configure your routes as usual:

    export const routes: Routes = [
      { path: 'main', component: MyComponent }
    ]
    

    then change routes array as desired and reset routes at app runtime (in app.component.ts contsructor)

    // app.component.ts
    constructor(private router: Router) {
      // modify routes
      if (subdomain === domain) {
       routes[0].path = ''; // or something more complex
      }
      // reset routes
      router.resetConfig(routes);
    }
    

    It also works with lazyloaded routes.

  16. liujingbreak commented on Dec 26, 2018

    @liujingbreak

    @lpikora Does it work in AOT mode? I am guessing it is not.

  17. lpikora commented on Dec 26, 2018

    @lpikora

    @liujingbreak yes, it works with AOT. The key is using router.resetConfig(routes) with customised routes array in runtime.

  18. liujingbreak commented on Jan 8, 2019

    @liujingbreak

    Thank you @lpikora, very nice of your solution.
    Also I found some obvious limitations in AOT mode, the fact is we can only change route configure with router.resetConfig(), but we can't bring new route configure like a new lazy module at runtime, it will report error

    core.js:14597 ERROR Error: Uncaught (in promise): Error: Cannot find module './lazy/lazy.module.ngfactory'
    Error: Cannot find module './lazy/lazy.module.ngfactory'
    

    Angular AOT engine goes through original route configure tree to find components and modules, compile them into ngfactory at compilation time. Any stuff new at runtime will be reported as missing ngfactory by Angular.

    And also I have not try it in Angular universal server-side rendering mode.

  19. unspike commented on Feb 13, 2019

    @unspike

    @liujingbreak have you found any possible approach to make it works with AOT?

  20. liujingbreak commented on Feb 22, 2019

    @liujingbreak

    @unspike I guess No, there is no ideal approach, since Angular AOT means all the route configurations must be laid down at compile time, not at run time.

    • As long as there is no new route added during runtime, we can adopt @lpikora 's approach.

    • If there is business requirement asks for such dynamic route to be created on-the-fly, then that route can not be a part of the original AOT appliaction.

    • My project does not ask me to have dynamic route on-the-fly, but I does hope we can resuse business route modules as much as possible cross different products like libraries, so we kinda use a tool to read our customized project configuration and have build script to rewrite TS source file before AOT build runs. As a workaround, quite like a Angular command line plugin.

  21. surfjedi commented on May 1, 2019

    @surfjedi

    Any one have any updates? I need this too?

  22. mayrmax commented on Jul 23, 2019

    @mayrmax

    I got it working using the ROUTES injection token.
    So it seems to still be possible with NG 8.1.

    export function getConfigRoutes():Route {
        return CONFIG_SUB_MODULE.getRoute();
    }
    @NgModule({
        imports: [RouterModule.forChild([])],
        providers: [
            {
                provide: ROUTES,
                multi: true,
                useFactory: getConfigRoutes,
                useValue: {}
            },
        ],
        exports: [RouterModule]
    })
    export class ConfigRoutingModule {
    }
    
  23. angular-automatic-lock-bot commented on Sep 9, 2019

    @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.

  24. locked and limited conversation to collaborators on Sep 9, 2019
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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions