Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Router ignores URL, when using custom ngDoBootstrap and createCustomElement

WHEN I use custom ngDoBootstrap function instead of default bootstrap: [AppComponent] like this:

@NgModule({
  imports:      [ BrowserModule, FormsModule, AppRoutingModule ],
  declarations: [ AppComponent, HelloComponent ],
  exports: [ AppComponent ],
  entryComponents: [ AppComponent ],
  // bootstrap: [AppComponent],
})
export class AppModule {
  constructor(private injector: Injector) {
  }

  public ngDoBootstrap(): any {
    const appElement = createCustomElement(AppComponent, { injector: this.injector });
    customElements.define('my-app', appElement);
  }
}

THEN Application routing is broken.

It ignores any changes in the URL and only works when I click on <a [routerLink]='...'>. Also the initial route / is not loaded.

It must be caused by the custom bootstrap mechanizm, because when I uncomment the bootstrap: [AppComponent], everything works fine.

Full code is available here: stackblitz sample (needs to be downloaded and run locally because of typescript version used by stackblitz)

How to make the routing work with custom app module bootstrapping?

like image 963
Liero Avatar asked Nov 07 '22 09:11

Liero


2 Answers

I managed to get it working by following this tutorial.

From what I understand, angular elements do not really support internal application routing (see this SO post) and this open github issue.

The solution is to manually instruct the router to navigate to internal routes when the location changes

export class AppModule {
  constructor(private injector: Injector, private router: Router,
    private location: Location) {
    const appElement = createCustomElement(AppComponent, { injector: this.injector });
   customElements.define('my-app', appElement);

    /**Add the lines below to your code**/
   //init router with starting path
    this.router.navigateByUrl(this.location.path(true));

    //on every route change tell router to navigate to defined route
    this.location.subscribe(data => {
      this.router.navigateByUrl(data.url);
    });

}

Here is the working stackblitz example

like image 81
David Avatar answered Nov 11 '22 13:11

David


in case of custom element, router.initialNavigation had to be called manually:

export class AppModule {
  constructor(private injector: Injector, private router: Router,
    private location: Location) {
    const appElement = createCustomElement(AppComponent, { injector: this.injector });
    customElements.define('my-app', appElement);


  public ngDoBootstrap(): void {
    // workaround for bug - initial route not loaded: https://github.com/angular/angular/issues/23740
    this.router.initialNavigation();
  }
}
like image 21
Liero Avatar answered Nov 11 '22 12:11

Liero