Asynchronously loading data routes and build route instructions for Angular 2

I try to build dynamic routes from angular2 (choosing a configuration route from the server), after that I analyze it and generate instructions for the component route (I have parent config and child routes to different components, because I do not know how to determine the route for the child component into one main.app.ts file).

The problem is when the application starts and tries to create routes config and routeGenerator does not yet create routes (async delay) can t parse routes data (because async delay, so routesData undefined now) and app is crashig. I don t parse routes data (because async delay, so routesData undefined now) and app is crashig. I don t know what to do with it. Looking for a lifecycle hood (some like @ Angular2BeforeAppStarted), but you haven’t found anything.

  import {Component, Input, OnChanges} from 'angular2/core'; import {RouteConfig, RouterOutlet, ROUTER_DIRECTIVES, Router} from 'angular2/router'; /* ------- !Angular 2 native components ---------*/ import {routeGenInstance} from '../../config/routes/patient_routes'; protected const BUILT_MODULE_PATH: string = '/built/modules/patients/'; @Component({ template: ` <router-outlet ></router-outlet> `, directives: [RouterOutlet, ROUTER_DIRECTIVES] }) @RouteConfig(routeGenInstance.getRouteDefinitions()) export class PatientsComponent { @Input(); constructor() {} } 

I also try to update the routes in the same way (but the application crashes immediately because my navigation link in the navigation component does not have the correct link path)

 import {RouteConfig, RouterOutlet, ROUTER_DIRECTIVES, Router} from 'angular2/router'; constructor( private router: Router ) { router.config([ routeGenInstance.getRoutesDefinition() ]) } 

Route definitions use an Async loader, so they are correct and work without asynchronous delay. I do not know how to make angular wait for the route definitions and start the application launch.

Please help me. Thanks.

UPD:

@Thierry thank you very much for your help again. You are a terrific friend and mentor. Last question (last). Can you tell me how I can define routeConfig in a single application file with a child routine definition? This is mean. I have main level routes to application files.

 { path: '/', name: 'Dashboard', component: DashboardComponent, useAsDefault: true }, { path: '/patients/...', name: 'Patients', component: PatientsComponent }, 

and Patient Components in Patients Component (@RouteConfig)

 { path: '/', // root is appRoot/patients/... name: 'PatientsList', component...}, { "name": "Chart", "path": "/chart/:id", component... }, 

How to determine the configuration of this route in only one app.file? (How to configure a route using additional routing in a single file)?

+7
asynchronous angular delay routes
source share
4 answers

You might want to get the configuration before downloading the application.

 var injector = Injector.resolveAndCreate([HTTP_PROVIDERS]); var http = injector.get(Http); http.get('routes.json').map(res => res.json()) .subscribe(data => { bootstrap(AppComponent, [ HTTP_PROVIDERS provide('routesConfig', { useValue: data }) ]); }); 

Then you can access the route configuration by injecting dependencies and synchronously:

 @Component({ (...) }) export class AppComponent { constructor(@Inject('routesConfig') private routesConfig, private router:Router) { // Configure here your routes } } 

These two questions may help you:

  • How to download an Angular 2 application asynchronously
  • angular2 boot file with data from ajax calls

Edit

You can use the Observable.forkJoin method to load the configuration of your route from different requests:

 var injector = Injector.resolveAndCreate([HTTP_PROVIDERS]); var http = injector.get(Http); Observable.forkJoin([ http.get('mainRoutes.json'), http.get('childRoutes.json') ]) .map(responses => { return { main: res[0].json(), children: res[1].json() }; }) .subscribe(data => { bootstrap(AppComponent, [ HTTP_PROVIDERS provide('routesConfig', { useValue: data }) ]); }); 

Edit1

I think you could try something like this:

 [ { path: '/patients/...', name: 'Patients', component: PatientsComponent, childRoutes: [ { path: '/', // root is appRoot/patients/... name: 'PatientsList', component... }, (...) ] } ] 

But you need to split the content to get different elements according to the hints you want to process:

  • one for the root:

     [ { path: '/patients/...', name: 'Patients', component: PatientsComponent } ] 
  • several for children. For example, for patients:

     [ { path: '/', // root is appRoot/patients/... name: 'PatientsList', component... }, (...) ] 
+6
source share

In the new router ( >= RC.3 ) https://angular.io/docs/js/latest/api/router/index/Router-class.html#!#resetConfig-anchor resetConfig you can use

 router.resetConfig([ { path: 'team/:id', component: TeamCmp, children: [ { path: 'simple', component: SimpleCmp }, { path: 'user/:name', component: UserCmp } ] } ]); 

See also https://github.com/angular/angular/issues/9472#issuecomment-229230093

  • You can load components asynchronously by providing SystemJsComponentResolver.
  • Now you can load routes asynchronously and strongly update the configuration using resetConfig.
  • After the AppModules are in the main, we will use those that will implement asynchronous loading of the configured files.

https://github.com/angular/angular/issues/11437#issuecomment-245995186 provides RC.6 Plunker

+4
source share

Check it out: DynamicalAsyncRouter

https://github.com/Longfld/DynamicalAsyncRouter

0
source share

Using Observables / Promises to translate routes is not a reliable solution, so the Angular router expects Route [] or Routes, but an HTTP request can only return Observable / Promise.

The Angular app gets initialized, but the route search process continues using Observables / Promises.

As Thierry Templer said, to get the configuration before starting the download, your solution will solve the problem.

Also check out @ ngx-i18n-router / core on github.

0
source share

All Articles