Angular Web Component routing reroutes to last component routed when we get back to the web component

789 Views Asked by At

We have built a web component with angular elements and consumed in a parent angular application.

But the problem seems to be with the web component routing.

It seems that the last loaded component loads up irrespective of the current url.

img 1

img 2

img 3

Now go to another route and back to the web component

|
|
V

img 4

The last image shows that the route one is still loading when the url is not pointing to route one.

Do any one have any idea on how to tackle this scenario.

Link to the projects

------------------------------------EDIT------------------------------------

Web Component Codes:

base component:

@Component({
  selector: 'app-route-comp',
  template: `<div>
      <ul>
        <li><a [routerLink]="['/base']">Base</a></li>
        <li><a [routerLink]="['/base', 'r1']">R1</a></li>
        <li><a [routerLink]="['/base', 'r2']">R2</a></li>
        <li><a [routerLink]="['/base', 'r3']">R3</a></li>
      </ul>
    </div>
    <router-outlet (activate)="onActivate($event)"></router-outlet>`,
})
export class RouteCompComponent implements OnInit, OnDestroy {
  constructor(private router: Router) {}

  ngOnInit(): void {}

  onActivate(event: Component) {
    console.log(event);
  }

  ngOnDestroy() {}
}

route one:

@Component({
  selector: 'app-route-one',
  template: '<p>route-one works!</p>',
})
export class RouteOneComponent {}

app component:

@Component({
  selector: 'app-root',
  template: '<router-outlet></router-outlet>',
})
export class AppComponent implements OnInit, OnDestroy {
  constructor(private router: Router) {}
  ngOnInit() {
    console.log('hello');
    this.router.initialNavigation();
  }

  ngOnDestroy() {}
}

routes:

const routes: Routes = [
  {
    path: 'base',
    component: RouteCompComponent,
    children: [
      {
        path: 'r1',
        component: RouteOneComponent,
      },
      {
        path: 'r2',
        component: RouteTwoComponent,
      },
      {
        path: 'r3',
        component: RouteThreeComponent,
      },
    ],
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

app module:

@NgModule({
  declarations: [
    AppComponent,
    RouteCompComponent,
    RouteOneComponent,
    RouteTwoComponent,
    RouteThreeComponent,
  ],
  imports: [BrowserModule, AppRoutingModule],
  providers: [],
})
export class AppModule {
  constructor(private injector: Injector) {}
  ngDoBootstrap() {
    const { injector } = this;

    const routeCompWC = createCustomElement(AppComponent, { injector });
    customElements.define('wc-1', routeCompWC);
  }
}

Consuming application:

app component:

@Component({
  selector: 'app-root',
  template: `<a routerLink="/base">base route</a>
    &nbsp;&nbsp;
    <a routerLink="/alt">alt route</a>

    <router-outlet></router-outlet>`,
})
export class AppComponent {}

routes:

const routes: Routes = [
  {
    path: 'base',
    component: OuterRouteComponent,
    children: [{ path: '**', component: OuterRouteComponent }],
  },
  {
    path: 'alt',
    component: OuterRouteTwoComponent,
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

outer component:

@Component({
  selector: 'app-outer-route',
  template: '<div #wc></div>',
})
export class OuterRouteComponent implements AfterViewInit {
  @ViewChild('wc') wc!: ElementRef<HTMLDivElement>;

  ngAfterViewInit() {
    const wc1El = document.createElement('wc-1') as NgElement &
      WithProperties<any>;

    this.wc.nativeElement.appendChild(wc1El);
  }
}

outer two component:

@Component({
  selector: 'app-outter-route-two',
  template: '<p>outer-route-two works!</p>',
})
export class OuterRouteTwoComponent {}

I believe this will do.

1

There are 1 best solutions below

1
On

After hitting and trying to fix the issue, worked up with a solution.

@Component({
  selector: 'app-root',
  template: '<router-outlet></router-outlet>',
})
export class AppComponent implements OnInit, OnDestroy {
  constructor(
    private router: Router,
    @Inject(DOCUMENT) private document: Document
  ) {}
  ngOnInit() {
    const fullHash = this.document.defaultView?.location.hash.substring(1);
    if (this.router.url !== '/' && this.router.url !== fullHash) {
      const hashSplit = fullHash?.split('?');
      const queryParams =
        hashSplit?.length && hashSplit?.length > 1
          ? hashSplit[1]
              .split('&')
              .map((ele) => ele.split('='))
              .reduce(
                (reduced: object, ele) => ({
                  ...reduced,
                  [ele[0]]: ele[1] ?? '',
                }),
                {}
              )
          : {};
      hashSplit?.length &&
        this.router.navigate([hashSplit[0]], {
          queryParams,
        });
    }
    this.router.initialNavigation();
  }
}