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.