Get Custom Route Data from lazy loaded route in top level component - javascript

I am using Angular 5 and I seem to not be able to get data from ActivatedRoute using methods stated in other answers to my question.
app.routes.ts
export const AppRoutes = [
{
path : '',
component: HomeView,
pathMatch: 'full', data: {key: 'home', label: 'Home'}},
{
path : 'about',
loadChildren: './+about/about.module#AboutModule'
},
{
path : 'account/:id',
loadChildren: './+account/account.module#AccountModule',
canActivate: [AuthGuard],
data: {key: 'account', label: 'My Account'}
},
];
app.component.ts
#Component({
selector: 'ou-app',
templateUrl: 'app.component.html',
styleUrls: ['../styles/main.scss'],
encapsulation: ViewEncapsulation.None
})
export class AppComponent implements OnInit {
constructor(
private router: Router,
private route: ActivatedRoute,
){}
ngOnInit(){
this.router.events.filter(event => event instanceof NavigationEnd).subscribe(event => {
console.log('router events console... ', this.route);
});
}
}
I can't seem to get the data from the route under snapshot, root, children, firstChild, everything is null, or undefined

The issue is that you are not at the route that you are trying to look at. You need to go through the child routes. There is an example here: Retrieving a data property on an Angular2 route regardless of the level of route nesting using ActivatedRoute
I was able to modify your code as follows using the info from the above link.
router.events
.filter(event => event instanceof NavigationEnd)
.map(() => this.activatedRoute)
.map(route => {
console.log(route.snapshot.data);
while (route .firstChild) route = route.firstChild;
return route;
})
.mergeMap(route => route.data)
.subscribe(x => {
console.log('router events console... ', x);
});
With this code I was able to get this:
Update: With RxJs v5.5 and above
ngOnInit() {
this.router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map((route) => {
while (route.firstChild) {
route = route.firstChild;
}
return route;
}),
mergeMap((route) => route.data))
.subscribe((event) => console.log('router events console... ', event));
}

I was able to solve my problem following this github issue: https://github.com/angular/angular/issues/11812
this.router.events.subscribe((data) => {
if (data instanceof RoutesRecognized) {
console.log(data.state.root.firstChild.data);
}
});

Related

How can I extract the id from the url?

The url looks like this:
http://localhost:4200/room/RECd4teOsdsro9YRcOMX/chat
I'm trying to extract the id part (RECd4teOsdsro9YRcOMX)
I tried the following:
chatRoomUid: string;
constructor(
private route: ActivatedRoute
) {}
ngOnInit() {
this.chatRoom$ = this.route.parent.parent.params.pipe(
tap(params => this.chatRoomUid = params.chatRoomUid),
switchMap(params => {
if (!params.chatRoomUid) return of(null);
this.chatRoomUid = params.chatRoomUid;
})
);
console.log(this.chatRoomUid); // returns undefined
}
How can I extract the id from the url and save it to my variable chatRoomUid?
Route:
{ path: 'room/:roomUid', loadChildren: () => import('#chatapp/pages/room/room.module').then(m => m.RoomModule) },
Edit: Added the routes
You're console.loging in a different context.
Remember Observables are asynchronous, thus you'd have to move console.log inside switchMap.
However, just produce a new Observable
chatRoomUid$: Observable<string>;
...
this.chatRoomUid$ = this.route.params.pipe(
map(params => params['roomUid'])
);
You can define your route like this
{path: 'room/:chatRoomUid/chat', component: ChatComponent}
Then in your component simply
import {ActivatedRoute} from '#angular/router';
constructor(private route:ActivatedRoute){}
ngOnInit(){
this.route.params.subscribe( params =>
console.log(params['chatRoomUid']);
)
}

How to change the header on parent component according to route

Using Angular 7.x, I want to change my parent header component accordingly to the child routes and if they're activated or not. So in my case
AppComponent
Feature Module <= detect changes here
Child Components of feature module
So my routing is very simple, the app-routing.module just contains the loading of the feature module with loadChildren, nothing fancy here.
Then this feature module contains the routes for the child components. There is one parentComponent, we call it ParentComponent which contains the router-outlet. There is also some headers that I want to change accordingly to the childs.
SO i have two child components: create, and ':id' (detail page). When I trigger these routes I need the parent component to just change their text content accordingly. So for example when the create page is triggered I want to add the header: "Create new item", and for the :id page I want to show "Detail page".
Now, I have figured out I need to subscribe to the router events or on the activatedRoute (or snapshot). I'm at a loss here so I don't really know what to do here.
My parent component looks like this now:
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute, Router } from '#angular/router';
#Component({
selector: 'parent-component',
templateUrl: './parent.component.html',
})
export class ParentComponent implements OnInit {
title = 'Parent Title';
// Check if it is possible to change the title according to the route
subtitle = 'Parent subtitle';
constructor(private readonly router: Router, private readonly route: ActivatedRoute) {}
ngOnInit(): void {
this.route.url.subscribe(data => {
if (this.route.snapshot.firstChild) {
console.log('yes', this.route.snapshot.firstChild);
// Change header with a if/else or switch case here
} else {
// Display standard text
console.log('no');
}
});
}
}
this is the output of the console.logs, notice in my real application the parent is named 'timesheets'.
Is there maybe another solution for this? Maybe a service, but all of the information is basically in the route already, so I'm trying to figure out if this is the way to go for my problem.
You can listen NavigationEnd events in ParentComponent or (I think) even better you can use a title service.
Solution 1:
In ParentComponent
import {NavigationEnd, Router} from '#angular/router';
import {filter} from 'rxjs/operators';
...
constructor(private router: Router, private readonly route: ActivatedRoute) {
this.subscribeRouterEvents();
}
subscribeRouterEvents = () => {
this.router.events.pipe(
filter(e => e instanceof NavigationEnd)
).subscribe(() => {
this.title = this.route.snapshot.data['title'];
// Assuming your route is like:
// {path: 'path', component: MyComponent, data: { title: 'Page Title'}}
});
Solution 2:
Using TitleService. Create a service that holds the page title, subscribe to title from ParentComponent and send new title to service from ChildComponent.
TitleService
#Injectable({
providedIn: 'root'
})
export class TitleService {
private defaultTitle = 'Page Title';
private titleSubject: BehaviorSubject<string> = new BehaviorSubject(this.defaultTitle);
public title: Observable<string>;
constructor(private titleService: Title) {
this.title = this.titleSubject.asObservable();
}
public setTitle(title: string) {
this.titleSubject.next(title);
}
}
ParentComponent
pageTitle = 'Page Title';
constructor(private titleService: TitleService) {}
ngOnInit(){
this.titleService.title.subscribe(value => this.pageTitle = value);
}
ChildComponent
pageTitle = 'Child Component Title';
constructor(private titleService: TitleService) {}
ngOnInit(){
this.titleService.setTitle(this.pageTitle);
}
You can try setting the title for a child as part of route like this.
const routes: Routes =[
{
path: 'create',
component: SomeComponent,
data : {header_title : 'some title'}
},
];
ngOnInit() {
this.title = this.route.data.subscribe(x => console.log(x));
}
and get the title in the child component and set that as header title using a service.

url property of NavigationEnd returns undefined (Angular 6)

I'm relatively new to front-end stuff, I was playing around with Angular 6, so the issue I'm facing with the following component is that NavigationEnd returns undefined and I can't figure out why:
import { Component, OnInit } from '#angular/core';
import { Router, NavigationEnd } from '#angular/router';
#Component({
selector: 'app-sidebar',
templateUrl: './sidebar.component.html',
styleUrls: ['./sidebar.component.scss']
})
export class SidebarComponent implements OnInit {
currentUrl: string;
constructor(private router: Router) {
router.events.subscribe(
(navEnd: NavigationEnd) => this.currentUrl = navEnd.url
);
}
}
router.events has different events, if you need to get the NavigationEnd you need to filter as follows. Try this,
router.events
.pipe(filter(e => e instanceof NavigationEnd))
.subscribe((e: NavigationEnd) => {
this.currentUrl = e.url;
});
You need to check which type of events you receive from the subscribe method.
Also you need to use this to access router ( it's a private variable)
constructor(private router: Router) {
this.router.events
.subscribe((event) => {
if (event instanceof NavigationEnd) {
this.currentUrl = event.url
console.log('NavigationEnd:', event);
}
})
I think what you are trying to achive is the following.
this.router.events.pipe(
filter((event) => event instanceof NavigationEnd),
map(() => this.activatedRoute)
).subscribe((event) => {
this.currentUrl = event.url
});
Inject ActivatedRoute in the constructor.
you can also use this in async, for checking a condition,
async getUrl(){
this._router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe((path:NavigationEnd)=>{
console.log("path",path);
this.activeUrl=path.url.split('/');
this.activeUrl.splice(0,1)
console.log("activeurl",this.activeUrl);
return this.activeUrl;
})
}
this.getUrl().then(()=>{
if(this.activeUrl[1]=='admin'){
//your code goes here
}
})
Quick Fix,
change the code
(navEnd: NavigationEnd) => this.currentUrl = navEnd.url
to
(navEnd: NavigationEnd) => this.currentUrl = router.url
Just one line change required to make it work on Angular 7
router.events.subscribe(() => this.currentUrl = this.router.url)

Angular 2 access parent routeparams from child component [duplicate]

How do I get the RouteParams from a parent component?
App.ts:
#Component({
...
})
#RouteConfig([
{path: '/', component: HomeComponent, as: 'Home'},
{path: '/:username/...', component: ParentComponent, as: 'Parent'}
])
export class HomeComponent {
...
}
And then, in the ParentComponent, I can easily get my username param and set the child routes.
Parent.ts:
#Component({
...
})
#RouteConfig([
{ path: '/child-1', component: ChildOneComponent, as: 'ChildOne' },
{ path: '/child-2', component: ChildTwoComponent, as: 'ChildTwo' }
])
export class ParentComponent {
public username: string;
constructor(
public params: RouteParams
) {
this.username = params.get('username');
}
...
}
But then, how can I get this same 'username' parameter in those child components? Doing the same trick as above, doesn't do it. Because those params are defined at the ProfileComponent or something??
#Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(
public params: RouteParams
) {
this.username = params.get('username');
// returns null
}
...
}
UPDATE:
Now that Angular2 final was officially released, the correct way to do this is the following:
export class ChildComponent {
private sub: any;
private parentRouteId: number;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.sub = this.route.parent.params.subscribe(params => {
this.parentRouteId = +params["id"];
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
ORIGINAL:
Here is how i did it using the "#angular/router": "3.0.0-alpha.6" package:
export class ChildComponent {
private sub: any;
private parentRouteId: number;
constructor(
private router: Router,
private route: ActivatedRoute) {
}
ngOnInit() {
this.sub = this.router.routerState.parent(this.route).params.subscribe(params => {
this.parentRouteId = +params["id"];
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
In this example the route has the following format: /parent/:id/child/:childid
export const routes: RouterConfig = [
{
path: '/parent/:id',
component: ParentComponent,
children: [
{ path: '/child/:childid', component: ChildComponent }]
}
];
You shouldn't try to use RouteParams in your ChildOneComponent.
Use RouteRegistry, instead!
#Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(registry: RouteRegistry, location: Location) {
route_registry.recognize(location.path(), []).then((instruction) => {
console.log(instruction.component.params['username']);
})
}
...
}
UPDATE: As from this pull request (angular beta.9): https://github.com/angular/angular/pull/7163
You can now access to the current instruction without recognize(location.path(), []).
Example:
#Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(_router: Router) {
let instruction = _router.currentInstruction();
this.username = instruction.component.params['username'];
}
...
}
I haven't tried it, yet
Further details here:
https://github.com/angular/angular/blob/master/CHANGELOG.md#200-beta9-2016-03-09
https://angular.io/docs/ts/latest/api/router/Router-class.html
UPDATE 2:
A small change as from angular 2.0.0.beta15:
Now currentInstruction is not a function anymore. Moreover, you have to load the root router. (thanks to #Lxrd-AJ for reporting)
#Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(_router: Router) {
let instruction = _router.root.currentInstruction;
this.username = instruction.component.params['username'];
}
...
}
As mentioned by Günter Zöchbauer, I used the comment at https://github.com/angular/angular/issues/6204#issuecomment-173273143 to address my problem. I used the Injector class from angular2/core to fetch the routeparams of the parent. Turns out angular 2 does not handle deeply nested routes. Maybe they'll add that in the future.
constructor(private _issueService: IssueService,
private _injector: Injector) {}
getIssues() {
let id = this._injector.parent.parent.get(RouteParams).get('id');
this._issueService.getIssues(id).then(issues => this.issues = issues);
}
I found an ugly but working solution, by requesting the parent (precisely the 2nd ancestor) injector, and by getting the RouteParams from here.
Something like
#Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(injector: Injector) {
let params = injector.parent.parent.get(RouteParams);
this.username = params.get('username');
}
}
RC5 + #angular/router": "3.0.0-rc.1 SOLUTION: It seems that this.router.routerState.queryParams has been deprecated. You can get the parent route params this way:
constructor(private activatedRoute: ActivatedRoute) {
}
this.activatedRoute.parent.params.subscribe(
(param: any) => {
let userId = param['userId'];
console.log(userId);
});
You can take component of parent route inside of child component from injector and then get any from child component. In you case like this
#Component({
...
})
export class ChildOneComponent {
public username: string;
constructor(
public params: RouteParams
private _injector: Injector
) {
var parentComponent = this._injector.get(ParentComponent)
this.username = parentComponent.username;
//or
this.username = parentComponent.params.get('username');
}
...
}
Passing Injector instance to constructor in child component may not be good if you want to write unit tests for your code.
The easiest way to work around this is to have a service class in the parent component, in which you save your required params.
#Component({
template: `<div><router-outlet></router-outlet></div>`,
directives: [RouterOutlet],
providers: [SomeServiceClass]
})
#RouteConfig([
{path: "/", name: "IssueList", component: IssueListComponent, useAsDefault: true}
])
class IssueMountComponent {
constructor(routeParams: RouteParams, someService: SomeServiceClass) {
someService.id = routeParams.get('id');
}
}
Then you just inject the same service to child components and access the params.
#Component({
template: `some template here`
})
class IssueListComponent implements OnInit {
issues: Issue[];
constructor(private someService: SomeServiceClass) {}
getIssues() {
let id = this.someService.id;
// do your magic here
}
ngOnInit() {
this.getIssues();
}
}
Note that you should scope such service to your parent component and its child components using "providers" in parent component decorator.
I recommend this article about DI and scopes in Angular 2: http://blog.thoughtram.io/angular/2015/08/20/host-and-visibility-in-angular-2-dependency-injection.html
In RC6, router 3.0.0-rc.2 (probably works in RC5 as well), you can take route params from the URL as a snapshot in case that params won't change, without observables with this one liner:
this.route.snapshot.parent.params['username'];
Don't forget to inject ActivatedRoute as follows:
constructor(private route: ActivatedRoute) {};
With RxJS's Observable.combineLatest, we can get something close to the idiomatic params handling:
import 'rxjs/add/operator/combineLatest';
import {Component} from '#angular/core';
import {ActivatedRoute, Params} from '#angular/router';
import {Observable} from 'rxjs/Observable';
#Component({ /* ... */ })
export class SomeChildComponent {
email: string;
id: string;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
Observable.combineLatest(this.route.params, this.route.parent.params)
.forEach((params: Params[]) => {
this.id = params[0]['id'];
this.email = params[1]['email'];
});
}
}
I ended up writing this kind of hack for Angular 2 rc.1
import { Router } from '#angular/router-deprecated';
import * as _ from 'lodash';
interface ParameterObject {
[key: string]: any[];
};
/**
* Traverse route.parent links until root router and check each level
* currentInstruction and group parameters to single object.
*
* e.g.
* {
* id: [314, 593],
* otherParam: [9]
* }
*/
export default function mergeRouteParams(router: Router): ParameterObject {
let mergedParameters: ParameterObject = {};
while (router) {
let currentInstruction = router.currentInstruction;
if (currentInstruction) {
let currentParams = currentInstruction.component.params;
_.each(currentParams, (value, key) => {
let valuesForKey = mergedParameters[key] || [];
valuesForKey.unshift(value);
mergedParameters[key] = valuesForKey;
});
}
router = router.parent;
}
return mergedParameters;
}
Now in view I collect parameters in view instead of reading RouteParams I just get them through router:
#Component({
...
})
export class ChildishComponent {
constructor(router: Router) {
let allParams = mergeRouteParams(router);
let parentRouteId = allParams['id'][0];
let childRouteId = allParams['id'][1];
let otherRandomParam = allParams.otherRandomParam[0];
}
...
}
In FINAL with little help of RXJS you can combine both maps (from child and parent):
(route) => Observable
.zip(route.params, route.parent.params)
.map(data => Object.assign({}, data[0], data[1]))
Other questions one might have:
Is it really a good idea to use above - because of coupling (couple child component with parent's param's - not on api level - hidden coupling),
Is it proper approach in term of RXJS (it would require hardcore RXJS user feedback ;)
You can do it on the snapshot with the following, but if it changes, your id property will not be updated.
This example also shows how you can subscribe to all ancestor parameter changes and look for the one you are interested in by merging all of the parameter observables. However, be careful with this method because there could be multiple ancestors that have the same parameter key/name.
import { Component } from '#angular/core';
import { ActivatedRoute, Params, ActivatedRouteSnapshot } from '#angular/router';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/observable/merge';
// This traverses the route, following ancestors, looking for the parameter.
function getParam(route: ActivatedRouteSnapshot, key: string): any {
if (route != null) {
let param = route.params[key];
if (param === undefined) {
return getParam(route.parent, key);
} else {
return param;
}
} else {
return undefined;
}
}
#Component({ /* ... */ })
export class SomeChildComponent {
id: string;
private _parameterSubscription: Subscription;
constructor(private route: ActivatedRoute) {
}
ngOnInit() {
// There is no need to do this if you subscribe to parameter changes like below.
this.id = getParam(this.route.snapshot, 'id');
let paramObservables: Observable<Params>[] =
this.route.pathFromRoot.map(route => route.params);
this._parametersSubscription =
Observable.merge(...paramObservables).subscribe((params: Params) => {
if ('id' in params) {
// If there are ancestor routes that have used
// the same parameter name, they will conflict!
this.id = params['id'];
}
});
}
ngOnDestroy() {
this._parameterSubscription.unsubscribe();
}
}
Getting RouteParams from parent component in Angular 8 -
I have a route http://localhost:4200/partner/student-profile/1234/info
Parent route - student-profile
Param - 1234 (student_id)
Child route - info
Accessing param in child route (info) -
Import
import { ActivatedRoute, Router, ParamMap } from '#angular/router';
Constructor
constructor(private activatedRoute: ActivatedRoute, private router: Router) { }
Accessing parent route params
this.activatedRoute.parent.paramMap.subscribe((params: ParamMap) => this.studentId = (params.get('student_id')));
Now, our variable studentId has the param value.

How to handle query parameters in angular 2

In my routable component I have
#RouteConfig {
{path: '/login', name: 'Login', component: LoginComponent}
}
But how do I get the query params if I go to app_url/login?token=1234?
RouteParams are now deprecated , So here is how to do it in the new router.
this.router.navigate(['/login'],{ queryParams: { token:'1234'}})
And then in the login component you can take the parameter,
constructor(private route: ActivatedRoute) {}
ngOnInit() {
// Capture the token if available
this.sessionId = this.route.queryParams['token']
}
Here is the documentation
To complement the two previous answers, Angular2 supports both query parameters and path variables within routing. In #RouteConfig definition, if you define parameters within a path, Angular2 handles them as path variables and as query parameters if not.
Let's take a sample:
#RouteConfig([
{ path: '/:id', component: DetailsComponent, name: 'Details'}
])
If you call the navigate method of the router like this:
this.router.navigate( [
'Details', { id: 'companyId', param1: 'value1'
}]);
You will have the following address: /companyId?param1=value1. The way to get parameters is the same for both, query parameters and path variables. The difference between them is that path variables can be seen as mandatory parameters and query parameters as optional ones.
Hope it helps you,
Thierry
UPDATE: After changes in router alpha.31 http query params no longer work (Matrix params #2774). Instead angular router uses so called Matrix URL notation.
Reference https://angular.io/docs/ts/latest/guide/router.html#!#optional-route-parameters:
The optional route parameters are not separated by "?" and "&" as they
would be in the URL query string. They are separated by semicolons ";"
This is matrix URL notation — something you may not have seen before.
It seems that RouteParams no longer exists, and is replaced by ActivatedRoute. ActivatedRoute gives us access to the matrix URL notation Parameters. If we want to get Query string ? paramaters we need to use Router.RouterState. The traditional query string paramaters are persisted across routing, which may not be the desired result. Preserving the fragment is now optional in router 3.0.0-rc.1.
import { Router, ActivatedRoute } from '#angular/router';
#Component ({...})
export class paramaterDemo {
private queryParamaterValue: string;
private matrixParamaterValue: string;
private querySub: any;
private matrixSub: any;
constructor(private router: Router, private route: ActivatedRoute) { }
ngOnInit() {
this.router.routerState.snapshot.queryParams["queryParamaterName"];
this.querySub = this.router.routerState.queryParams.subscribe(queryParams =>
this.queryParamaterValue = queryParams["queryParameterName"];
);
this.route.snapshot.params["matrixParameterName"];
this.route.params.subscribe(matrixParams =>
this.matrixParamterValue = matrixParams["matrixParameterName"];
);
}
ngOnDestroy() {
if (this.querySub) {
this.querySub.unsubscribe();
}
if (this.matrixSub) {
this.matrixSub.unsubscribe();
}
}
}
We should be able to manipulate the ? notation upon navigation, as well as the ; notation, but I only gotten the matrix notation to work yet. The plnker that is attached to the latest router documentation shows it should look like this.
let sessionId = 123456789;
let navigationExtras = {
queryParams: { 'session_id': sessionId },
fragment: 'anchor'
};
// Navigate to the login page with extras
this.router.navigate(['/login'], navigationExtras);
This worked for me (as of Angular 2.1.0):
constructor(private route: ActivatedRoute) {}
ngOnInit() {
// Capture the token if available
this.sessionId = this.route.snapshot.queryParams['token']
}
(For Childs Route Only such as /hello-world)
In the case you would like to make this kind of call :
/hello-world?foo=bar&fruit=banana
Angular2 doesn't use ? nor & but ; instead. So the correct URL should be :
/hello-world;foo=bar;fruit=banana
And to get those data :
import { Router, ActivatedRoute, Params } from '#angular/router';
private foo: string;
private fruit: string;
constructor(
private route: ActivatedRoute,
private router: Router
) {}
ngOnInit() {
this.route.params.forEach((params: Params) => {
this.foo = params['foo'];
this.fruit = params['fruit'];
});
console.log(this.foo, this.fruit); // you should get your parameters here
}
Source : https://angular.io/docs/ts/latest/guide/router.html
Angular2 v2.1.0 (stable):
The ActivatedRoute provides an observable one can subscribe.
constructor(
private route: ActivatedRoute
) { }
this.route.params.subscribe(params => {
let value = params[key];
});
This triggers everytime the route gets updated, as well: /home/files/123 -> /home/files/321
The simple way to do that in Angular 7+ is to:
Define a path in your ?-routing.module.ts
{ path: '/yourpage', component: component-name }
Import the ActivateRoute and Router module in your component and inject them in the constructor
contructor(private route: ActivateRoute, private router: Router){ ... }
Subscribe the ActivateRoute to the ngOnInit
ngOnInit() {
this.route.queryParams.subscribe(params => {
console.log(params);
// {page: '2' }
})
}
Provide it to a link:
<a [routerLink]="['/yourpage']" [queryParams]="{ page: 2 }">2</a>
Angular 4:
I have included JS (for OG's) and TS versions below.
.html
<a [routerLink]="['/search', { tag: 'fish' } ]">A link</a>
In the above I am using the link parameter array see sources below for more information.
routing.js
(function(app) {
app.routing = ng.router.RouterModule.forRoot([
{ path: '', component: indexComponent },
{ path: 'search', component: searchComponent }
]);
})(window.app || (window.app = {}));
searchComponent.js
(function(app) {
app.searchComponent =
ng.core.Component({
selector: 'search',
templateUrl: 'view/search.html'
})
.Class({
constructor: [ ng.router.Router, ng.router.ActivatedRoute, function(router, activatedRoute) {
// Pull out the params with activatedRoute...
console.log(' params', activatedRoute.snapshot.params);
// Object {tag: "fish"}
}]
}
});
})(window.app || (window.app = {}));
routing.ts (excerpt)
const appRoutes: Routes = [
{ path: '', component: IndexComponent },
{ path: 'search', component: SearchComponent }
];
#NgModule({
imports: [
RouterModule.forRoot(appRoutes)
// other imports here
],
...
})
export class AppModule { }
searchComponent.ts
import 'rxjs/add/operator/switchMap';
import { OnInit } from '#angular/core';
import { Router, ActivatedRoute, Params } from '#angular/router';
export class SearchComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private router: Router
) {}
ngOnInit() {
this.route.params
.switchMap((params: Params) => doSomething(params['tag']))
}
More infos:
"Link Parameter Array"
https://angular.io/docs/ts/latest/guide/router.html#!#link-parameters-array
"Activated Route - the one stop shop for route info" https://angular.io/docs/ts/latest/guide/router.html#!#activated-route
For Angular 4
Url:
http://example.com/company/100
Router Path :
const routes: Routes = [
{ path: 'company/:companyId', component: CompanyDetailsComponent},
]
Component:
#Component({
selector: 'company-details',
templateUrl: './company.details.component.html',
styleUrls: ['./company.component.css']
})
export class CompanyDetailsComponent{
companyId: string;
constructor(private router: Router, private route: ActivatedRoute) {
this.route.params.subscribe(params => {
this.companyId = params.companyId;
console.log('companyId :'+this.companyId);
});
}
}
Console Output:
companyId : 100
According to Angular2 documentation you should use:
#RouteConfig([
{path: '/login/:token', name: 'Login', component: LoginComponent},
])
#Component({ template: 'login: {{token}}' })
class LoginComponent{
token: string;
constructor(params: RouteParams) {
this.token = params.get('token');
}
}
Angular 5+ Update
The route.snapshot provides the initial value of the route parameter
map. You can access the parameters directly without subscribing or
adding observable operators. It's much simpler to write and read:
Quote from the Angular Docs
To break it down for you, here is how to do it with the new router:
this.router.navigate(['/login'], { queryParams: { token:'1234'} });
And then in the login component (notice the new .snapshot added):
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.sessionId = this.route.snapshot.queryParams['token']
}
In Angular 6, I found this simpler way:
navigate(["/yourpage", { "someParamName": "paramValue"}]);
Then in the constructor or in ngInit you can directly use:
let value = this.route.snapshot.params.someParamName;

Categories