Come ottenere i parametri di query dall'URL in Angular 5?


181

Sto usando la 5.0.3 angolare, vorrei avviare la mia applicazione con un sacco di parametri di query come /app?param1=hallo&param2=123. Tutti i suggerimenti forniti in Come ottenere parametri di query dall'URL in Angular 2? Non funziona per me.

Qualche idea su come far funzionare i parametri della query?

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

Questa funzione privata mi aiuta a ottenere i miei parametri, ma non penso che sia la strada giusta nel nuovo ambiente angolare.

[aggiornamento:] Sembra la mia app principale

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

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    // would like to get query parameters here...
    // this.route...
  }
}

Stai usando i router? Da dove proviene l'URL?
Vinod Bhavnani,

Sì, disporre di ActivatedRoute. Ho aggiornato la mia domanda per mostrare come appare il mio componente principale.
Lars,

Puoi mostrarmi anche la costante del tuo percorso, dove hai impostato tutti i percorsi?
Vinod Bhavnani,

const appRoutes: Routes = [{path: "one", componente: PageOneComponent}, {path: "", redirectTo: "/ one", pathMatch: "full"}, {path: "**", redirectTo: "/ uno"} ]; La mia costante di rotta. Vorrei ottenere tutti i parametri nell'app store principale in un DTO, quindi passare a un'altra pagina. La navigazione della pagina funziona come previsto, ma ottengo i parametri della query principalmente dalla mia funzione 'getQueryParameter'. Mi rendo conto nella tua domanda che esiste qualcosa che ho dimenticato. Devo contrassegnare i nomi dei miei parametri ovunque?
Lars,

Sì, nei tuoi percorsi devi anche definire i parametri. Se controlli i documenti di routing su angular.io, puoi vedere come definiscono i parametri su un determinato percorso. Qualcosa del genere {path: 'abc /: param1', component: componentClassName}
Vinod Bhavnani,

Risposte:


239

In Angular 5, è possibile accedere ai parametri della query iscrivendosi a this.route.queryParams.

Esempio: /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'];
    });
}

al contrario, è possibile accedere alle variabili del percorso this.route.snapshot.params

Esempio: /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;
}

15
Secondo i documenti di Angular 6 , l'utilizzo di ActivatedRoute.queryParams e .params è sconsigliato e potrebbe essere deprecato nelle versioni future; vedi aggiornamento qui
grreeenn,

1
@ShubhenduVaid spiega perché, dovrebbero usare ngOnInit invece del costruttore. Le migliori pratiche utilizzeranno l'osservabile RxJS, quindi utilizzeranno l'approccio dichiarativo quando si lavora con gli osservabili, quindi usando l'asincronizzazione su html
coderpatomx

118

Questa è la soluzione più pulita per me

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');
  }
}

Questo è utile, grazie. A partire dall'angolare 6.0.8, sto usando questo e funziona per me: this.route.snapshot.queryParams ["firstParamKey"]
fluidguid

2
Questo funziona per me in Angular8. this.route.snapshot.queryParamMap funziona. this.route.snapshot.paramMap non funziona per me.
Romeo Profijt,

89

So che OP ha chiesto la soluzione Angular 5, ma tuttavia per tutti coloro che si imbattono in questa domanda per le versioni angolari più recenti (6+). Citando Documenti , riguardo ActivatedRoute.queryParams (su cui si basano la maggior parte delle altre risposte):

Sono ancora disponibili due proprietà precedenti. Sono meno capaci dei loro sostituti, scoraggiati e possono essere deprecati in una futura versione angolare.

params - Un osservabile che contiene i parametri obbligatori e facoltativi specifici del percorso. Utilizzare invece paramMap.

queryParams - Un osservabile che contiene i parametri di query disponibili per tutte le rotte. Utilizzare invece queryParamMap.

Secondo Docs , il modo semplice per ottenere i parametri della query sarebbe simile al seguente:

constructor(private route: ActivatedRoute) { }

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

Per modi più avanzati (ad es. Riutilizzo avanzato dei componenti) consultare questo capitolo di Documenti.

MODIFICARE:

Come indicato correttamente nei commenti seguenti, questa risposta è errata, almeno per il caso specificato da OP.

OP chiede di ottenere parametri di query globali (/ app? Param1 = hallo & param2 = 123); in questo caso dovresti usare queryParamMap (proprio come nella risposta @ dapperdan1985).

paramMap, d'altra parte, viene utilizzato su parametri specifici del percorso (ad es. / app /: param1 /: param2, risultante in / app / hallo / 123).

Grazie a @JasonRoyle e @daka per averlo segnalato.


10
Questo non dovrebbe essere utilizzato per queryParamMapnon paramMaprecuperare i parametri della stringa di query?
Jason Royle

2
@JasonRoyle Sembra che tu abbia ragione, paramMapnon funziona.
daka,

1
Questa risposta deve essere corretta secondo i commenti sopra.
daka,

@JasonRoyle, daka, hai ragione, grazie per averlo sottolineato. Corretta la risposta
grreeenn,

Codice di lavoro perfetto trovato: jsonworld.com/blog/…
Soni Kumari

17

Puoi anche usare HttpParams , come:

  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;
  }

1
Chiarisco, ho due domini che puntano a siti di lingue diverse. localhost / -> En, localhost /? lang = fr -> francese. E ho di routing: path: '', redirectTo: '/list' . This.route.snapshot non funziona per me perché reindirizza To / list che elimina la queryString 'lang'. Ma questa soluzione funziona per me.
Ryan Huang,

Come @RyanHuang ho lo stesso problema. Ma questa soluzione ha funzionato sulla mia prima prova.
Gi1ber7,

Trova la soluzione migliore di sopra: jsonworld.com/blog/…
Soni Kumari

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

constructor(private route: ActivatedRoute) {}

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

AGGIORNARE

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
    }
}

6
che sembra non essere abbastanza, ottengo ActivatedRouteSnapshot ma queryParams è un oggetto vuoto, anche i parametri sono vuoti e .queryParamMap.get ('name') restituisce null. Sembra che ngOnInit () sia troppo presto per ottenere tali parametri di query.
Lars,

in realtà se vuoi ottenere questi parametri dovresti cambiare il tuo percorso.
Dmitry Grinko,

Ho circa 10 parametri in ordine diverso. Pertanto, devo utilizzare parametri di query denominati. E come posso impostare il mio AppComponent principale per rendermi conto che ci sono 10 parametri. url / myprogram? a = 1 & b = 2 & c = 4 ... sembra che abbia un problema? Devo indirizzare ogni parametro a un altro componente? Spero di no.
Lars,

Hai provato questo? this.route.snapshot.queryParamMap
Dmitry Grinko

1
@DmitryGrinko inserire un ID entità in una route non è un modello errato, consente un collegamento profondo a una vista di dettaglio.
Karl,


5

Parametri Query e Path (Angular 8)

Per url come https://myapp.com/user/666/read?age=23 utilizzare

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
    // ...
  })

AGGIORNARE

Nel caso in cui si utilizzi this.router.navigate([someUrl]);e i parametri della query siano incorporati nella someUrlstringa, angolare codifica un URL e si ottiene qualcosa del genere https://myapp.com/user/666/read%3Fage%323 - e la soluzione sopra genererà risultati errati ( queryParams sarà vuoto e i parametri del percorso possono essere incollati all'ultimo parametro del percorso se si trova alla fine del percorso). In questo caso cambia la modalità di navigazione in questo

this.router.navigateByUrl(someUrl);

1
Grazie @Kamil Kiełczewski, mi hai salvato la giornata
Tan Nguyen,

4

Mi sono imbattuto in questa domanda quando stavo cercando una soluzione simile ma non avevo bisogno di nulla come il routing a livello di applicazione completa o più moduli importati.

Il seguente codice funziona benissimo per il mio uso e non richiede moduli aggiuntivi o importazioni.

  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 uscite:

param1 = hello
param2 = 123

3

Angular Router fornisce il metodo parseUrl (url: string) che analizza l'URL in UrlTree . Una delle proprietà di UrlTree sono queryParams. Quindi puoi fare qualcosa come:

this.router.parseUrl(this.router.url).queryParams[key] || '';

Si prega di non pubblicare più risposte identiche a domande diverse. Ci sono alcuni consigli utili su questa pratica qui
David Buck

Utilizzare questo se non è necessario gestire le modifiche all'URL, ovvero i parametri sono già disponibili nell'URL corrente. Fallo nel modo osservabile altrimenti.
Tom,

2

Sfortunatamente, la soluzione più pulita non è la soluzione più estensibile. Nelle versioni recenti di Angular, nelle altre risposte si suggerisce che è possibile ottenere facilmente i parametri della query utilizzando ActivatedRoute Injectible e utilizzando specificamente la proprietà snapshot:

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

o la proprietà iscriviti (utilizzata nei casi in cui la stringa di query verrà aggiornata, ad esempio navigando attraverso gli ID utente):

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

Sono qui per dirti che queste soluzioni hanno un difetto spalancato che non è stato risolto da tempo: https://github.com/angular/angular/issues/12157

Tutto sommato, l'unica soluzione a prova di proiettile è usare il buon vecchio javascript alla vaniglia. In questo caso, ho creato un servizio per la manipolazione degli 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']
        }
    }
}

1

Quando si dispone di un oggetto route vuoto, è principalmente dovuto al fatto che non si utilizza un router-outlet in app.component.html.

Senza questo, non sarai in grado di ottenere un oggetto route significativo con oggetti secondari non vuoti, in particolare parametri e queryParams.

Prova ad aggiungere <router-outlet><router-outlet>poco prima di chiamare il tuo <app-main-component></app-main-component>

Prima di ciò, assicurati di avere il tuo parametro di query pronto nel routing delle app> che esporta la classe Route utilizzata dal componente App:

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

L'ultima cosa ovviamente, per ottenere il tuo param, uso personalmente this.route.snapshot.params.dynamicParamdove dynamicParam è il nome usato nel tuo componente di routing delle app :)


1

Fai attenzione ai tuoi percorsi. Un "redirectTo" rimuoverà | eliminerà qualsiasi parametro di query.

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

Ho chiamato il mio componente principale con parametri di query come "/ main? Param1 = a & param2 = b e presumo che i miei parametri di query arrivino nel metodo" ngOnInit () "nel componente principale prima che l'inoltro di reindirizzamento abbia effetto.

Ma questo è sbagliato. Il reindirizzamento verrà prima, elimina i parametri della query e chiama il metodo ngOnInit () nel componente principale senza parametri di query.

Ho cambiato la terza riga dei miei percorsi in

{path: "", component: PageOneComponent},

e ora i miei parametri di query sono accessibili nei componenti principali ngOnInit e anche in PageOneComponent.


1

Trovato in: I componenti principali si svuotano Params da ActivatedRoute

Ha funzionato per me:

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();
  }

}

0

Ci siamo appena imbattuti nello stesso problema e la maggior parte delle risposte qui sembrano risolverlo solo per il routing interno angolare, e poi alcuni di essi per i parametri di percorso che non sono gli stessi dei parametri di richiesta.

Immagino di avere un caso d'uso simile alla domanda originale di Lars.

Per me il caso d'uso è ad esempio il monitoraggio dei referral:

Funzionamento angolare mycoolpage.com, con instradamento dell'hash, quindi mycoolpage.comreindirizza a mycoolpage.com/#/. Per il rinvio, tuttavia, mycoolpage.com?referrer=foodovrebbe essere utilizzabile anche un collegamento come quello . Sfortunatamente, Angular rimuove immediatamente i parametri della richiesta, andando direttamente a mycoolpage.com/#/.

Qualsiasi tipo di "trucco" con l'utilizzo di un componente vuoto + AuthGuard e ottenere queryParamso queryParamMap, sfortunatamente, non ha funzionato per me. Erano sempre vuoti.

La mia soluzione hacky è stata quella di gestirla in un piccolo script in index.htmlcui ottiene l'URL completo, con parametri di richiesta. Quindi ottengo il valore del parametro di richiesta tramite la manipolazione della stringa e lo imposto sull'oggetto finestra. Un servizio separato quindi gestisce l'ottenimento dell'ID dall'oggetto finestra.

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;
}

Servizio

declare var window: any;

@Injectable()
export class ReferrerService {

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

0

Soluzione semplice

 // 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")
                  }

0

http: // localhost: 4200 / prodotti ORDER = popolari

Possiamo accedere ai parametri della query dell'ordine in questo modo:

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

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

C'è anche queryParamMap, che restituisce un osservabile con un oggetto paramMap.

Dato il seguente URL del percorso:

http: // localhost: 4200 / prodotti order = popolari & filter = new

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

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


0

A, penso Angular 8:

ActivatedRoute.paramsè stato sostituito da ActivatedRoute.paramMap ActivatedRoute.queryParamsè stato sostituito da ActivatedRoute.queryParamMap


-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);

 });

  }

-9

Se non si utilizza il router angolare, provare, querystring . Installalo

npm install --save querystring

al tuo progetto. Nel tuo componente fai qualcosa del genere

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

Il substring(1)è necessario perché se si ha qualcosa di simile '/mypage?foo=bar', allora il nome della chiave per sarà?foo

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.