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!
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.
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With