Angular load routing from REST service before init

2020-07-23 04:29发布

I am looking into the possibility for Angular 8 to dynamically create the routing from a REST service. This idea is that a user can create pages which should be available for access by routing on the web page.

I have seen options to dynamically add routes, however I would like to have the routes loaded before the rest of the app, so that when a user would access: 'website/generatedPage' the routing is in place before the app is fully loaded.

How do I make sure the routes from the REST service are in place before the app continues with the routing options?

The following piece of code adds the routing to late:

    constructor(
    private sitemapService: SitemapService,
    private router: Router
) {
    this.sitemapService.getSiteMap().then(result => {
        result.forEach(sitemapItem => {
            this.router.config.push({ path: sitemapItem.pageName, component: PageComponent });
        });
    });
}

With this code you can navigate to the page when the app is aready loaded, however, when you would directly request the route, it is not loaded yet.

Thank you in advance!

2条回答
Animai°情兽
2楼-- · 2020-07-23 04:57

I have found a solution, however it is more of a workaround. For my situation it works, but still if anyone has a cleaner solution it will be mutch appreciated.

In the appModule I have defined routes for all predefined routes. I have a website module where all pages created by the user will be initialized.

So the workaround:

In the app-routing I send all non defined routes to the website module:

{ path: '**', loadChildren: () => import('./website/website.module').then(module => module.WebsiteModule) }

In the website module I forward all calls to a PageComponent

path: '**', component: PageComponent

In the page component I request the page from the rest service, if it is a 404 I redirect to the predefined PageNotFound.

As I said, it is definitely not clean but it works. So any clean solutions which let me create a RoutingConfig which is fully defined from rest would be much appreciated.

查看更多
该账号已被封号
3楼-- · 2020-07-23 04:59

Ok, so I had this exact same issue and I was actually going to use your "solution" when I stumbled up on these three articles and used a combination of them to come up with the solution.

References:

https://long2know.com/2017/11/angular-dynamic-routes-and-application-initialization/ https://medium.com/codegg/pre-loading-user-specific-routes-in-angular-ce829430e1cb https://www.tektutorialshub.com/angular/angular-how-to-use-app-initializer/#where-to-use-app-initializer

My use case: I need to create routes based on a GET response

Here's what worked for me:

1. First, I created a new app-init service:


import { Injectable } from '@angular/core';
import { Router } from '@angular/router';

@Injectable()
export class AppInitService {

  constructor(private Router: Router) {}

  init() {
    return new Promise<void>((resolve, reject) => {

        // Simple example from an array. In reality, I used the response of
        // a GET. Important thing is that the app will wait for this promise to resolve
        const newDynamicRoutes = ['bulbasaur','charmander','squirtle']
        const routes = this.Router.config;

        newDynamicRoutes.forEach(routeName => {
          routes.push({ path: routeName, component: <YourComponent> });
        });

        this.Router.resetConfig(routes);
        resolve();
    });
  }
}

2. Then, I use it in app.module.ts with APP_INITIALIZER

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { AppInitService } from './services/app-init/app-init.service'; // New service that I created

...

export function initializeApp(appInitService: AppInitService) {
  return (): Promise<any> => { 
    return appInitService.init();
  }
}

...

  providers: [
    AppInitService,
    {
      provide: APP_INITIALIZER,
      useFactory: initializeApp,
      multi: true,
      deps: [AppInitService]
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

This works like a charm. It lets me create routes based on the response from an API.

查看更多
登录 后发表回答