Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 routing, how to get access to the language param in an url

I am building an app where the first url segment represents the language of the interface, like :

/en/customer/3
/en/shop

My router is set up like this:

{ path: ':lang/customers/:id', component: CustomerComponent },
{ path: ':lang/shop', component: ShopComponent },

I want to use the language param from the url (lang = 'en' in this example) in the bootstrapped AppComponent or in a translation service. I have access to this param in the ShopComponent and CustomerComponent, but nowhere else in the code. When I enter this in AppComponent:

constructor(private activatedRoute: ActivatedRoute, private router : Router) {
}

ngOnInit() {
  this.router.routerState.root.params.subscribe((params: Params) => {
    console.log('params: ',params);
  }
  this.activatedRoute.params.subscribe((params: Params) => {
    console.log('params: ',params);
  }
}      

I get two empty objects. Also the url param remains empty.

What am I doing wrong? Maybe more importantly, I am obviously missing some conceptual understanding of routers, but I cannot find any helpful information in the docs or elsewhere.

Thanks for your help!

like image 424
Carlo Roosen Avatar asked Dec 19 '16 16:12

Carlo Roosen


2 Answers

Trying to answer my own question, I think there is NO easy way to do it the way I thought. The router setup like

{ path: ':lang/customers/:id', component: CustomerComponent } 

attaches the entire path to the CustomerComponent, making lang and id both available parameters there. From this perspective it is clear why those parameters are not accessible outside CustomerComponent.

What I ended up doing is redefine my router like so:

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';

import { LanguageComponent, CustomerComponent, ShopComponent } from "./";

@NgModule({
    imports: [
    RouterModule.forRoot([
      { path: ':lang', component: LanguageComponent ,
        children: [
          { path: 'shop', component: ShopComponent },
          { path: 'customer/:id', component: CustomerComponent },
          { path: '**', redirectTo: '/shop', pathMatch: 'full' }
        ]
      },
            { path: '**', redirectTo: '/en', pathMatch: 'full' }
    ])
  ],
  exports: [
    RouterModule
  ]
})
export class AppRoutingModule {}

Then I created a LanguageComponent as a Routing Component.

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';

import { TranslateService } from './'
@Component({
  template : '<router-outlet></router-outlet>'
})
export class LanguageComponent implements OnInit {

  constructor( private activatedRoute : ActivatedRoute, private translateService: TranslateService) {
  }

  ngOnInit() {
    this.activatedRoute.params.subscribe( (params : Params) => {
      this.translateService.setLanguage( params['lang'] );
    });    
  }
}

Then I store the language in TranslateService, which is globally available.

like image 123
Carlo Roosen Avatar answered Nov 10 '22 01:11

Carlo Roosen


Check out this post about getting route params

Getting the parameter from a route

this.subscription = this.activatedRoute.params.subscribe(
 (param: any) => {
   let language = param['lang'];
   this.chosenLang = language; // Access to the lang
 });

In your component where you want to get the route paramter

app.component.ts

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

@Component({
  selector: 'my-app',
  template: `<blah></blah>`,
  styles: []
})
export class AppComponent implements OnInit, OnDestroy {
  private subscription: Subscription;
  chosenLang: string = "";

  constructor(private activatedRoute: ActivatedRoute) { }

  ngOnInit() {
    // subscribe to router event
    this.subscription = this.activatedRoute.params.subscribe(
     (param: any) => {
       let language = param['lang'];
       this.chosenLang = language; // Access to the lang
     });
  }

  ngOnDestroy() {
    // prevent memory leak by unsubscribing
    this.subscription.unsubscribe();
  }

}
like image 34
Logan H Avatar answered Nov 09 '22 23:11

Logan H