Search code examples
javascriptangularangular-routingangular-router

Getting language prefix as parameter from Angular 6 router


I have an Angular (6.0.3) application and I want to use the language as a common prefix to all routes, something like /en/foo/bar. My route definition src/app/submodule/submodule.routes.ts looks like this:

export const submoduleRoutes = [
    { path: ':lingua/foo/bar', component: FooBarComponent },
];

My root component src/app/app.component.ts:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router, ActivatedRoute, Event, NavigationEnd } from '@angular/router';

import { filter } from 'rxjs/operators';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit, OnDestroy {
  title = 'app';
  private sub: any;


  constructor(private router: Router, private route: ActivatedRoute) {

    this.router.events.pipe(
      filter((event:Event) => event instanceof NavigationEnd)
    ).subscribe(x => console.log(x));
  };

  ngOnInit() {
    this.sub = this.route.params.subscribe(params => {
       console.log(params);
    });
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }
}

When I navigate to /xy/foo/bar, the FooBarComponent gets rendered. But I am not able to retrieve language prefix in the root component. The params hash is empty.

The console output first displays {} for the empty params, and then the NavigationEnd event.

The same code works as expected in the FooBarComponent. Obviously, the root component is the wrong place to get the parameters.

My goal is actually to get the lingua parameter for all components, so that I can set the correct language. I know that I could also store the language in a cookie or local storage but I need bookmarkable URLs for the multi-lingual content.

In case that matters, the source code is at https://github.com/gflohr/Lingua-Poly (commit 12608dc). The route in question is defined in https://github.com/gflohr/Lingua-Poly/blob/master/src/app/main/main.routes.ts (at the end, :lingua/mytest.


Solution

  • You need to make them children of the App.component for it to work.

    For example:

    const routes = [
      { path: ":lingua", component: AppComponent, loadChildren: 'app/main/main.module#MainModule' },
      { path: "", pathMatch: "full", redirectTo: "/en" }
    ]
    

    This will load all the child routes from main module, but allow AppComponent to access the lingua parameter.

    You will then need to remove the :lingua part from your child route

    Here is a StackBlitz example