¿Cómo obtener parámetros de consulta de URL en Angular 5?

181

Estoy usando angular 5.0.3, me gustaría iniciar mi aplicación con un montón de parámetros de consulta como /app?param1=hallo&param2=123. ¿Cada consejo dado en Cómo obtener parámetros de consulta de url en Angular 2? no funciona para mi

¿Alguna idea de cómo hacer funcionar los parámetros de consulta?

private getQueryParameter(key: string): string {
  const parameters = new URLSearchParams(window.location.search);
  return parameters.get(key);
}

Esta función privada me ayuda a obtener mis parámetros, pero no creo que sea la forma correcta en un nuevo entorno angular.

[actualización:] Mi aplicación principal se ve así

@Component({...})
export class AppComponent implements OnInit {

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    // would like to get query parameters here...
    // this.route...
  }
}
Lars
fuente
¿Estás usando enrutadores? ¿De dónde viene la URL?
Vinod Bhavnani
Sí, tiene una ruta activada. Actualicé mi pregunta para mostrar cómo se ve mi componente principal.
Lars el
¿También me puede mostrar su ruta constante, donde ha configurado todas las rutas?
Vinod Bhavnani
const appRoutes: Routes = [{path: "one", componente: PageOneComponent}, {path: "", redirectTo: "/ one", pathMatch: "full"}, {path: "**", redirectTo: "/ uno"} ]; Mi ruta constante. Me gustaría obtener todos los parámetros en la aplicación principal almacenarlo en un DTO, luego navegar a otra página. La navegación de página funciona como se esperaba, pero obtengo los parámetros de consulta en main solo por mi función 'getQueryParameter'. Me doy cuenta en su pregunta de que existe algo que he olvidado. ¿Debo marcar mis nombres de parámetros en algún lugar?
Lars el
Sí, en sus rutas, también necesita definir los parámetros. Si verifica los documentos de enrutamiento en angular.io, puede ver cómo definen los parámetros en una ruta en particular. Algo como esto {ruta: 'abc /: param1', componente: componentClassName}
Vinod Bhavnani

Respuestas:

239

En Angular 5, se accede a los parámetros de consulta suscribiéndose a this.route.queryParams.

Ejemplo: /app?param1=hallo&param2=123

param1: string;
param2: string;
constructor(private route: ActivatedRoute) {
    console.log('Called Constructor');
    this.route.queryParams.subscribe(params => {
        this.param1 = params['param1'];
        this.param2 = params['param2'];
    });
}

mientras que las variables de ruta son accedidas por this.route.snapshot.params

Ejemplo: /param1/:param1/param2/:param2

param1: string;
param2: string;
constructor(private route: ActivatedRoute) {
    this.param1 = this.route.snapshot.params.param1;
    this.param2 = this.route.snapshot.params.param2;
}
Vijayendra Mudigal
fuente
15
Según los documentos de Angular 6 , se desaconseja el uso de ActivatedRoute.queryParams y .params y puede quedar obsoleto en futuras versiones; ver actualización aquí
grreeenn
1
@ShubhenduVaid explica por qué, deberían usar ngOnInit en lugar del constructor. La mejor práctica será usar RxJS observable, luego usar un enfoque declarativo al trabajar con observables, luego usar async en el html
coderpatomx
118

Esta es la solución más limpia para mí.

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

export class MyComponent {
  constructor(
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    const firstParam: string = this.route.snapshot.queryParamMap.get('firstParamKey');
    const secondParam: string = this.route.snapshot.queryParamMap.get('secondParamKey');
  }
}
dapperdan1985
fuente
Esto es útil, gracias. A partir de angular 6.0.8, estoy usando esto y funciona para mí: this.route.snapshot.queryParams ["firstParamKey"]
fluidguid
2
Esto funciona para mí en Angular8. this.route.snapshot.queryParamMap funciona. this.route.snapshot.paramMap no funciona para mí.
Romeo Profijt
89

Sé que OP solicitó la solución Angular 5, pero aún así para todos ustedes que se topan con esta pregunta para las versiones angulares más nuevas (6+). Citando los documentos , con respecto a ActivatedRoute.queryParams (en los que se basan la mayoría de las otras respuestas):

Dos propiedades antiguas aún están disponibles. Son menos capaces que sus reemplazos, desalentados, y pueden ser desaprobados en una futura versión angular.

params: un observable que contiene los parámetros obligatorios y opcionales específicos de la ruta. Use paramMap en su lugar.

queryParams: un observable que contiene los parámetros de consulta disponibles para todas las rutas. Utilice queryParamMap en su lugar.

Según los documentos , la forma simple de obtener los parámetros de consulta se vería así:

constructor(private route: ActivatedRoute) { }

ngOnInit() {
    this.param1 = this.route.snapshot.paramMap.get('param1');
    this.param2 = this.route.snapshot.paramMap.get('param2');
}

Para formas más avanzadas (por ejemplo, reutilización avanzada de componentes), consulte este capítulo de Documentos.

EDITAR:

Como se indicó correctamente en los comentarios a continuación, esta respuesta es incorrecta, al menos para el caso especificado por OP.

OP solicita obtener parámetros de consulta globales (/ app? Param1 = hallo & param2 = 123); en este caso, debe usar queryParamMap (al igual que en la respuesta @ dapperdan1985).

paramMap, por otro lado, se usa en parámetros específicos de la ruta (por ejemplo, / app /: param1 /: param2, lo que resulta en / app / hallo / 123).

Gracias a @JasonRoyle y @daka por señalarlo.

Grreeenn
fuente
10
¿No debería esto estar usando queryParamMapno paramMappara buscar parámetros de cadena de consulta?
Jason Royle
2
@JasonRoyle Parece que tienes razón, paramMapno funciona.
Daka
1
Esta respuesta debe corregirse según los comentarios anteriores.
Daka
@JasonRoyle, Daka, tienes razón, gracias por señalarlo. Corrigió la respuesta.
grreeenn
Código de trabajo perfecto encontrado: jsonworld.com/blog/…
Soni Kumari
17

También puede usar HttpParams , como:

  getParamValueQueryString( paramName ) {
    const url = window.location.href;
    let paramValue;
    if (url.includes('?')) {
      const httpParams = new HttpParams({ fromString: url.split('?')[1] });
      paramValue = httpParams.get(paramName);
    }
    return paramValue;
  }
a5tr0
fuente
1
Solo aclare, tengo dos dominios que apuntan a un sitio de idioma diferente. localhost / -> Es, localhost /? lang = fr -> francés. Y he de enrutamiento: path: '', redirectTo: '/list' . La this.route.snapshot no funciona para mí porque redirige a / list que elimina la cadena de consulta 'lang'. Pero esta solución funciona para mí.
Ryan Huang
Como @RyanHuang, tengo el mismo problema. Pero esta solución funcionó en mi primera prueba.
Gi1ber7
Encuentre una solución mejor que la anterior: jsonworld.com/blog/…
Soni Kumari
11
import { ParamMap, Router, ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

ngOnInit() {
    console.log(this.route.snapshot.queryParamMap);
}

ACTUALIZAR

import { Router, RouterStateSnapshot } from '@angular/router';

export class LoginComponent {
    constructor(private router: Router) {
        const snapshot: RouterStateSnapshot = router.routerState.snapshot;
        console.log(snapshot);  // <-- hope it helps
    }
}
Dmitry Grinko
fuente
66
eso parece no ser suficiente, obtengo ActivatedRouteSnapshot pero queryParams es un objeto vacío, los parámetros también están vacíos y .queryParamMap.get ('nombre') devuelve nulo. Parece que ngOnInit () es demasiado pronto para obtener dichos parámetros de consulta.
Lars el
En realidad, si desea obtener estos parámetros, debe cambiar su ruta.
Dmitry Grinko
Tengo alrededor de 10 parámetros en un orden diferente. Por lo tanto, debo usar parámetros de consulta con nombre. ¿Y cómo configuro mi AppComponent principal para darme cuenta de que hay 10 parámetros? url / myprogram? a = 1 & b = 2 & c = 4 ... parece que tengo un problema? ¿Necesito enrutar cada parámetro a otro componente? Espero que no.
Lars el
¿Intentaste este? this.route.snapshot.queryParamMap
Dmitry Grinko
1
@DmitryGrinko poner una ID de entidad en una ruta no es un mal patrón, permite un enlace profundo a una vista detallada.
Karl
5

Parámetros de consulta y ruta (angular 8)

Para url como https://myapp.com/user/666/read?age=23 use

import { combineLatest } from 'rxjs';
// ...

combineLatest( [this.route.paramMap, this.route.queryParamMap] )
  .subscribe( ([pathParams, queryParams]) => {
    let userId = pathParams.get('userId');    // =666
    let age    = queryParams.get('age');      // =23
    // ...
  })

ACTUALIZAR

En caso de que use this.router.navigate([someUrl]);y sus parámetros de consulta estén incrustados en una someUrlcadena, entonces angular codifica una URL y obtendrá algo como esto https://myapp.com/user/666/read%3Fage%323 - y la solución anterior dará un resultado incorrecto ( queryParams estará vacío, y los parámetros de ruta se pueden pegar al último parámetro de ruta si está al final de la ruta). En este caso, cambie la forma de navegación a este

this.router.navigateByUrl(someUrl);
Kamil Kiełczewski
fuente
1
Gracias @Kamil Kiełczewski, me salvaste el día
Tan Nguyen
4

Tropecé con esta pregunta cuando estaba buscando una solución similar, pero no necesitaba nada como enrutamiento de nivel de aplicación completo o más módulos importados.

El siguiente código funciona muy bien para mi uso y no requiere módulos adicionales o importaciones.

  GetParam(name){
    const results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
    if(!results){
      return 0;
    }
    return results[1] || 0;
  }

  PrintParams() {
    console.log('param1 = ' + this.GetParam('param1'));
    console.log('param2 = ' + this.GetParam('param2'));
  }

http://localhost:4200/?param1=hello&param2=123 salidas:

param1 = hello
param2 = 123
Junco
fuente
3

Angular Router proporciona el método parseUrl (url: string) que analiza url en UrlTree . Una de las propiedades de UrlTree son queryParams. Entonces puedes hacer algo como:

this.router.parseUrl(this.router.url).queryParams[key] || '';
Adam Michalak
fuente
No publique múltiples respuestas idénticas a diferentes preguntas. Hay algunos consejos útiles sobre esta práctica aquí
David Buck
Use esto si no necesita lidiar con los cambios de URL, es decir, los parámetros ya están disponibles en la URL actual. Hazlo de la manera observable de lo contrario.
Tom
2

Desafortunadamente, la solución más limpia no es la solución más extensible. En versiones recientes de Angular, se sugiere en las otras respuestas que puede obtener fácilmente los parámetros de consulta utilizando el Inyectable ActivatedRoute y utilizando específicamente la propiedad de instantánea:

this.route.snapshot.queryParamMap.get('param')

o la propiedad de suscripción (utilizada en los casos en que la cadena de consulta se actualizará, por ejemplo, navegando por los ID de usuario):

this.route.queryParamMap.subscribe(params => console.log(params));

Estoy aquí para decirles que estas soluciones tienen una falla enorme que no se ha resuelto por algún tiempo: https://github.com/angular/angular/issues/12157

Con todo, la única solución a prueba de balas es usar un buen JavaScript antiguo de vainilla. En este caso, creé un servicio para la manipulación de URL:

import { Injectable } from '@angular/core';
import { IUrl } from './iurl';

@Injectable()
export class UrlService {
    static parseQuery(url: string): IUrl {
        const query = url.slice(url.indexOf('?')+1).split('&').reduce( (acc,query) => {
            const parts = query.split('=');
            acc[parts[0]] = parts[1];
            return acc;
        }, {});

        return {
            a: query['a'],
            b: query['b'],
            c: query['c'],
            d: query['d'],
            e: query['e']
        }
    }
}
Donato
fuente
1

Cuando tiene un objeto de ruta vacío, se debe principalmente al hecho de que no está utilizando una salida de enrutador en su app.component.html.

Sin esto, no podrá obtener un objeto de ruta significativo con subObjetos no vacíos, particularmente params y queryParams.

Intenta agregar <router-outlet><router-outlet>justo antes de llamar a tu <app-main-component></app-main-component>

Antes de eso, asegúrese de tener su parámetro de consulta listo en el enrutamiento de aplicaciones> que exporta la clase Ruta utilizada por el componente Aplicación:

param: '/param/:dynamicParam', path: MyMainComponent

Lo último, por supuesto, para obtener su parámetro, yo personalmente uso this.route.snapshot.params.dynamicParamdonde dynamicParam es el nombre utilizado en su componente de enrutamiento de aplicaciones :)

andrea06590
fuente
1

Ten cuidado con tus rutas. Un "redirectTo" eliminará | colocará cualquier parámetro de consulta.

const appRoutes: Routes [
 {path: "one", component: PageOneComponent},
 {path: "two", component: PageTwoComponent},
 {path: "", redirectTo: "/one", pathMatch: full},
 {path: "**", redirectTo: "/two"}
]

Llamé a mi componente principal con parámetros de consulta como "/ main? Param1 = a & param2 = by supongo que mis parámetros de consulta llegan al método" ngOnInit () "en el componente principal antes de que el reenvío de redireccionamiento surta efecto.

Pero esto está mal. La redirección vendrá antes, descarte los parámetros de consulta y llame al método ngOnInit () en el componente principal sin parámetros de consulta.

Cambié la tercera línea de mis rutas a

{path: "", component: PageOneComponent},

y ahora mis parámetros de consulta son accesibles en los componentes principales ngOnInit y también en PageOneComponent.

Lars
fuente
1

Se encuentra en: Los componentes principales obtienen parámetros vacíos de ActivatedRoute

Trabajó para mi:

import {Component, OnDestroy, OnInit} from '@angular/core';
import { Router, ActivatedRoute, Params, RoutesRecognized } from '@angular/router';

@Component({
  selector: 'app-navigation-bar',
  templateUrl: './navigation-bar.component.html',
  styleUrls: ['./navigation-bar.component.scss']
})
export class NavigationBarComponent implements OnInit, OnDestroy {
  private sub: any;
  constructor(private route: ActivatedRoute, private router: Router) {}

  ngOnInit() {
    this.sub = this.router.events.subscribe(val => {
      if (val instanceof RoutesRecognized) {
        console.log(val.state.root.firstChild.params);
      }
    });
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }

}
Yonatan Ayalon
fuente
0

Simplemente tropecé con el mismo problema y la mayoría de las respuestas aquí parecen resolverlo solo para el enrutamiento interno angular, y luego algunos de ellos para parámetros de ruta que no son lo mismo que los parámetros de solicitud.

Supongo que tengo un caso de uso similar a la pregunta original de Lars.

Para mí, el caso de uso es, por ejemplo, el seguimiento de referencias:

Angular funcionando mycoolpage.com, con enrutamiento hash, por lo que mycoolpage.comredirige a mycoolpage.com/#/. Para referencia, sin embargo, un enlace como mycoolpage.com?referrer=footambién debería ser utilizable. Desafortunadamente, Angular elimina inmediatamente los parámetros de solicitud, yendo directamente a mycoolpage.com/#/.

Cualquier tipo de 'truco' con el uso de un componente vacío + AuthGuard y obtener queryParamso queryParamMap, desafortunadamente, no funcionó para mí. Siempre estaban vacíos.

Mi solución hacky terminó siendo manejar esto en un pequeño script en el index.htmlque se obtiene la URL completa, con los parámetros de solicitud. Luego obtengo el valor de parámetro de solicitud a través de la manipulación de cadenas y lo configuro en un objeto de ventana. Un servicio separado se encarga de obtener la identificación del objeto de la ventana.

script index.html

const paramIndex = window.location.href.indexOf('referrer=');
if (!window.myRef && paramIndex > 0) {
  let param = window.location.href.substring(paramIndex);
  param = param.split('&')[0];
  param = param.substr(param.indexOf('=')+1);
  window.myRef = param;
}

Servicio

declare var window: any;

@Injectable()
export class ReferrerService {

  getReferrerId() {
    if (window.myRef) {
      return window.myRef;
    }
    return null;
  }
}
seBaka28
fuente
0

Solución simple

 // in routing file
       {
            path: 'checkout/:cartId/:addressId',
            loadChildren: () => import('./pages/checkout/checkout.module').then(m => m.CheckoutPageModule)
          },

    // in Component file

            import { Router, ActivatedRoute } from '@angular/router';

                 constructor(
                      private _Router: ActivatedRoute
                  ) { }

                  ngOnInit() {
                    this.cartId = this._Router.snapshot.params.cartId;
                    this.addressId = this._Router.snapshot.params.addressId;
                    console.log(this.addressId, "addressId")
                    console.log(this.cartId, "cartId")
                  }
Shashwat Gupta
fuente
0

http: // localhost: 4200 / products? order = popular

Podemos acceder al parámetro de consulta de pedido de esta manera:

this.route.queryParams
      .filter(params => params.order)
      .subscribe(params => {
        console.log(params)// {order: "popular"}

        this.order = params.order;
        console.log(this.order); // popular
      });
  }

También hay queryParamMap, que devuelve un observable con un objeto paramMap.

Dada la siguiente ruta URL:

http: // localhost: 4200 / products? order = popular & filter = new

this.route.queryParamMap.subscribe(params => {
  this.orderObj = {...params.keys, ...params};
});

Fuente: https://alligator.io/angular/query-parameters/

San jaisy
fuente
0

En, creo que Angular 8:

ActivatedRoute.paramsha sido reemplazado por ActivatedRoute.paramMap ActivatedRoute.queryParamsha sido reemplazado por ActivatedRoute.queryParamMap

Marvin
fuente
-1
/*
Example below url with two param (type and name) 
URL : http://localhost:4200/updatePolicy?type=Medicare%20Insurance&name=FutrueInsurance
*/ 
  constructor(private route: ActivatedRoute) {
    //Read url query parameter `enter code here`
  this.route.queryParams.subscribe(params => {
    this.name= params['type'];
    this.type= params['name'];
    alert(this.type);
    alert(this.name);

 });

  }
Kaji Islam
fuente
-9

Si no está utilizando el enrutador angular, intente con la cadena de consulta . Instalarlo

npm install --save querystring

a su proyecto En tu componente haz algo como esto

import * as qs from 'querystring';
...
ngOnInit() {
   const params = qs.parse(window.location.search.substring(1));
   ...
}

El substring(1)es necesaria porque si tiene algo como esto '/mypage?foo=bar'entonces el nombre clave para será?foo

Chuk Lee
fuente