I need to get param from route which is not parent and not even grand-parent, it\'s simply somewhere above, along the path to root. I am aware of approaches like shown in An
I ran into the same problem and after finding this answer I created this function called getParams() that gets all the params of the parents and the current root.
It combines all the params and reduces into a single map.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { ServicosService } from '@service/core/servicos.service';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { map, combineAll } from 'rxjs/operators';
@Injectable()
export abstract class HttpServiceRouted {
constructor(
protected http: HttpClient,
protected servicos: ServicosService,
protected route: ActivatedRoute
) {}
getParams() {
return Observable.from(this.route.pathFromRoot.concat(this.route)).pipe(
map(route => route.params),
combineAll(),
map((params: any[]) =>
params.reduce(
// tslint:disable-next-line:no-shadowed-variable
(map: Map<string, string>, obj) => {
Object.keys(obj).forEach(key => {
map.set(key, obj[key]);
});
return map;
},
new Map<string, string>()
)
)
);
}
}
Usage:
this.getParams().subscribe((params: ParamMap) => {
const id = params.get('id');
});
Generally, I think your approach does make sense.
I do not know the exact background for the code, but it does feel like a child component wanting to know lots about parent instance data, and I would agree with @Aravind's comment that this is likely best dealt with in global state management solutions such as redux or ngrx. That being said, if this is all you would need it for, I understand you would not want to introduce that level of complexity.
I would only make minor adjustments to your rxchain so it is more readable.
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Model } from './model';
import { ModelService } from './model.service';
@Component({
...
})
export class ModelsComponent implements OnInit {
models: Model[];
constructor(
private route: ActivatedRoute,
private modelService: ModelService) { }
ngOnInit() {
const paramsArr = this.route.pathFromRoot;
Observable.from(paramsArr)
.map(route => route.params)
.filter(params => params.containerId)
.switchMap(containerId => this.modelService.getAllBelongingTo(containerId))
.subscribe(
(models: Model[]) => {
// yay! we got sth
this.models = models;
},
error => {
// handle big nono
}
);
}
}
Note however this implementation will only set this.models when there is a containerId as a parameter to a parent
EDIT 1: Fixed typos