Skip to content

Instantly share code, notes, and snippets.

@lydemann
Created July 4, 2018 15:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lydemann/cdae0b7adb5b213c723692ff2aad979e to your computer and use it in GitHub Desktop.
Save lydemann/cdae0b7adb5b213c723692ff2aad979e to your computer and use it in GitHub Desktop.
import { Injectable } from '@angular/core';
import { ActivatedRoute, Router, RoutesRecognized } from '@angular/router';
import { QueryParamServiceInterface } from '@app/core/query-param/query-param.interface';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { filter, first, map, mergeMap, pluck, share, take } from 'rxjs/operators';
@Injectable()
export class QueryParamService {
private routerIsReadySubject: BehaviorSubject<boolean>;
private routerIsReady$: Observable<boolean>;
constructor(private router: Router, private activatedRoute: ActivatedRoute) {
this.routerIsReadySubject = new BehaviorSubject(false);
this.routerIsReady$ = this.routerIsReadySubject
.asObservable()
.pipe(filter((isReady: boolean) => isReady), take(1), share());
const routeSub = this.router.events
.pipe(filter((event) => event instanceof RoutesRecognized), first())
.subscribe((event) => {
// because this can run before router is ready which gives no query params: https://github.com/angular/angular/issues/12157
this.routerIsReadySubject.next(true);
});
}
public getQueryParam(queryParamKey: string): Observable<any> {
return this.routerIsReady$.pipe(
mergeMap(() => this.activatedRoute.queryParams),
filter((params) => {
return params[queryParamKey];
}),
map((params) => JSON.parse(params[queryParamKey]))
);
}
public getQueryParamNullable(queryParamKey: string): Observable<any> {
return this.routerIsReady$.pipe(
mergeMap(() => this.activatedRoute.queryParams),
pluck(queryParamKey)
);
}
public setQueryParam(queryParamKey, queryParamValue) {
// Because queryParams is readonly
// because this can run before router is ready,
// which gives no query params even if they are set: https://github.com/angular/angular/issues/12157
this.routerIsReady$.subscribe(() => {
this.setQueryParamsFn(queryParamKey, queryParamValue);
});
}
public removeQueryParam(queryParamKey) {
this.routerIsReady$.subscribe(() => {
this.removeQueryParamsFn(queryParamKey);
});
}
public clear(): void {
this.router.navigate([], {
relativeTo: this.activatedRoute,
queryParams: {}
});
}
private removeQueryParamsFn(queryParamKey) {
const queryParamsClone = Object.assign({}, this.activatedRoute.snapshot.queryParams);
delete queryParamsClone[queryParamKey];
this.router.navigate([], {
relativeTo: this.activatedRoute,
queryParams: queryParamsClone
});
}
private setQueryParamsFn(queryParamKey, queryParamValue) {
const queryParamsClone = Object.assign({}, this.activatedRoute.snapshot.queryParams);
queryParamsClone[queryParamKey] = JSON.stringify(queryParamValue);
this.router.navigate([], {
relativeTo: this.activatedRoute,
queryParams: queryParamsClone
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment