route-param.decorator.ts 2.46 KiB
import { ActivatedRoute } from '@angular/router';
import { Observer } from 'rxjs';
import { map } from 'rxjs/operators';
import { hookBefore, hookFinally } from './hooks';
function ParamFromMap<K extends 'paramMap' | 'queryParamMap'>(
  param: string = null,
  routeProperty: string = 'route',
  mapName: K
) {
  return (prototype: any, property: string | symbol): void => {
    let resolvedParam = param || property.toString();
    if (resolvedParam.endsWith('$')) {
      resolvedParam = resolvedParam.substr(0, resolvedParam.length - 1);
    const subscription = Symbol.for(`RouteParamSub_${resolvedParam}`);
    hookBefore(prototype, 'ngOnInit', function() {
      const route: ActivatedRoute = (this as any)[routeProperty];
      const observer: Observer<string> = (this as any)[property];
      if (!route || !(mapName in route)) {
        throw new Error(`this.${routeProperty.toString()} must contains an ActivatedRoute`);
      if (observer === null || !('next' in observer) || typeof observer.next !== 'function') {
        throw new Error(`this.${property.toString()} must implement Observer`);
      const snapshot = route.snapshot[mapName];
      if (snapshot) {
        observer.next(snapshot.get(resolvedParam));
      (this as any)[subscription] = route[mapName].pipe(map(p => p.get(resolvedParam))).subscribe(observer);
    });
    hookFinally(prototype, 'ngOnDestroy', function() {
      this[subscription].unsubscribe();
    });
/**
 * Décorateur pour récuperer un paramètre de la route.
 * La propriété décorée doit implémenter Observer<string>.
 * @param {string|null} param Nom du paramètre. Par défaut égal au nom de la propriété minus le '$' final.
 * @param {string} routeProperty nom de la propriété du Component contenant l'ActivatedRoute. Par défaut 'route'.
export function RouteParam(param: string = null, routeProperty: string = 'route') {
  return ParamFromMap(param, routeProperty, 'paramMap');
/**
 * Décorateur pour récuperer un paramètre de la requête.
 * La propriété décorée doit implémenter Observer<string>.
 * @param {string|null} param Nom du paramètre. Par défaut égal au nom de la propriété minus le '$' final.
 * @param {string} routeProperty nom de la propriété du Component contenant l'ActivatedRoute. Par défaut 'route'.
export function QueryParam(param: string = null, routeProperty: string = 'route') {
  return ParamFromMap(param, routeProperty, 'queryParamMap');