Best practice of retrieving params and queryParams in Angular 2
I guess if you need to access both at the same time the snapshot is a better option.
Not tested (just from the top of my head)
ngOnInit() {
this.route
.params
.subscribe(params => {
this.query = params['id'];
this.offset = this.route.snapshot.queryParams['pageSize'];
# find entries this.entryService.findEntries(this.query, this.pageSize);
});
});
}
I've faced this dilemma recently and the best solution fitting my needs I've found is to use Observable.merge
.
Using snapshot is not good if you want to watch changes from params queryParams within the same component (i.e search with filters).
Observable.forkJoin
has the limitation that both observables must be triggered in order to work, so if you have a scenario where there might be changes in params or in queryParams, but not necessarily in both, forkJoin wouldn't hep you.
Observable.merge
on the other hand is triggered with either one of them being triggered. Of course, this also has some drawbacks since you might have two callbacks being called one after the other (at the beginning with params and queryParams).
Here is an example:
Observable.merge(
this.route.params.map(params => this.handleParams(params)),
this.route.queryParams.map(queryParams => this.handleQueryParams(queryParams))
)
.subscribe(
() => this.onParamsOrQueryParamsChange()
);
The Observable.combineLatest is a solution in this situation, isn't it?
Observable
.combineLatest(
this.route.params,
this.route.queryParams,
(params: any, queryParams: any) => {
return {
id: +params.id,
pageSize: queryParams.pageSize ? +queryParams.pageSize: null
}
})
.subscribe(bothParams => {
this.id = bothParams.id;
this.pageSize = bothParams.pageSize;
});
What about using a forkJoin?
ForkJoin allows you to join two observables and wait for the response of both them. You can see the documentation here and read more about it here.
As for your code it would look something like this:
ngOnInit() {
Observable.forkJoin(this.route.params, this.route.queryParams).subscribe(bothParams => {
// bothParams is an array, on the first index we have the router.params
// on the second index we have the queryParams
this.query = bothParams[0].query;
this.pageSize = bothParams[0].pageSize;
this.entryService.findEntries(this.query, this.pageSize);
});
}
You might need to add imports:
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';