Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular load routing from REST service before initialization

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!

like image 895
PieterSchool Avatar asked Dec 08 '19 14:12

PieterSchool


People also ask

Which route Guard can be used to pre fetch the data from the back end API before activating the route?

The Resolve guard (pre-fetching route data) Lazy loading an NgModule. The CanLoad guard (check before loading feature module assets)

Why Activatedroute is used in Angular?

ActivatedRoutelink. Provides access to information about a route associated with a component that is loaded in an outlet. Use to traverse the RouterState tree and extract information from nodes.

How do I enable Angular routing?

Add the AppRoutingModule link The router is dedicated to routing and imported by the root AppModule . By convention, the module class name is AppRoutingModule and it belongs in the app-routing.module.ts in the src/app directory. Run ng generate to create the application routing module.

What is Loadchildren in Angular routing?

LoadChildrenlinkA function that returns a set of routes to load.


1 Answers

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.

like image 92
Jesse Williams Avatar answered Nov 15 '22 04:11

Jesse Williams