Wie bekomme ich Abfrageparameter von der URL in Angular 5?

180

Ich verwende Angular 5.0.3. Ich möchte meine Anwendung mit einer Reihe von Abfrageparametern wie starten /app?param1=hallo&param2=123. Jeder Tipp in Wie bekomme ich Abfrageparameter von der URL in Angular 2? funktioniert bei mir nicht

Irgendwelche Ideen, wie Abfrageparameter funktionieren?

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

Diese private Funktion hilft mir, meine Parameter abzurufen, aber ich denke nicht, dass dies in einer neuen Angular-Umgebung der richtige Weg ist.

[Update:] Meine Haupt-App sieht aus wie

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

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    // would like to get query parameters here...
    // this.route...
  }
}
Lars
quelle
Verwenden Sie Router? Woher kommt die URL?
Vinod Bhavnani
Ja, haben Sie eine ActivatedRoute. Ich habe meine Frage aktualisiert, um zu zeigen, wie meine Hauptkomponente aussieht.
Lars
Können Sie mir auch Ihre Routenkonstante zeigen, in der Sie alle Routen eingerichtet haben?
Vinod Bhavnani
const appRoutes: Routes = [{Pfad: "eins", Komponente: PageOneComponent}, {Pfad: "", redirectTo: "/ one", pathMatch: "full"}, {Pfad: "**", redirectTo: "/ einer"} ]; Meine Routenkonstante. Ich möchte alle Parameter in der Haupt-App in einem DTO speichern und dann zu einer anderen Seite navigieren. Die Seitennavigation funktioniert wie erwartet, aber ich erhalte die Abfrageparameter hauptsächlich nur über meine Funktion 'getQueryParameter'. Ich erkenne in Ihrer Frage, dass es etwas gibt, das ich vergessen habe. Muss ich meine Parameternamen irgendwo markieren?
Lars
Ja, auf Ihren Routen müssen Sie auch die Parameter definieren. Wenn Sie die Routing-Dokumente auf angle.io überprüfen, können Sie sehen, wie sie Parameter auf einer bestimmten Route definieren. So etwas wie das {path: 'abc /: param1', component: componentClassName}
Vinod Bhavnani

Antworten:

237

In Angular 5 wird durch Abonnieren auf die Abfrageparameter zugegriffen this.route.queryParams .

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

Auf die Pfadvariablen wird von zugegriffen this.route.snapshot.params

Beispiel: /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
quelle
15
Laut Angular 6- Dokumenten wird von der Verwendung von ActivatedRoute.queryParams und .params abgeraten und ist möglicherweise in zukünftigen Versionen veraltet. siehe Update hier
Grreeenn
1
@ShubhenduVaid erklären, warum sie ngOnInit anstelle des Konstruktors verwenden sollten. Best Practice ist die Verwendung von RxJS Observable, dann die Verwendung eines deklarativen Ansatzes bei der Arbeit mit Observables und die Verwendung von Async auf dem HTML
Coderpatomx
117

Dies ist die sauberste Lösung für mich

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
quelle
Das ist hilfreich, danke. Ab Winkel 6.0.8 verwende ich dies und es funktioniert für mich: this.route.snapshot.queryParams ["firstParamKey"]
fluidguid
2
Das funktioniert bei mir in Angular8. this.route.snapshot.queryParamMap funktioniert. this.route.snapshot.paramMap funktioniert bei mir nicht.
Romeo Profijt
89

Ich weiß, dass OP nach einer Angular 5-Lösung gefragt hat, aber dennoch nach allen, die auf diese Frage für neuere (6+) Angular-Versionen stoßen. Zitieren der Dokumente zu ActivatedRoute.queryParams (auf denen die meisten anderen Antworten basieren):

Zwei ältere Immobilien sind noch verfügbar. Sie sind weniger leistungsfähig als ihre Ersetzungen, werden entmutigt und sind möglicherweise in einer zukünftigen Angular-Version veraltet .

params - Ein Observable, das die erforderlichen und optionalen Parameter enthält, die für die Route spezifisch sind. Verwenden Sie stattdessen paramMap.

queryParams - Ein Observable, das die Abfrageparameter enthält, die für alle Routen verfügbar sind. Verwenden Sie stattdessen queryParamMap.

Nach dem Text & Tabellen , die einfache Möglichkeit , die Abfrage params bekommen würde wie folgt aussehen:

constructor(private route: ActivatedRoute) { }

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

Weitere Informationen (z. B. erweiterte Wiederverwendung von Komponenten) finden Sie in diesem Dokumentenkapitel.

BEARBEITEN:

Wie in den Kommentaren unten richtig angegeben, ist diese Antwort falsch - zumindest für den von OP angegebenen Fall.

OP fragt nach globalen Abfrageparametern (/ app? Param1 = hallo & param2 = 123); In diesem Fall sollten Sie queryParamMap verwenden (genau wie in der Antwort @ dapperdan1985).

paramMap wird dagegen für routenspezifische Parameter verwendet (z. B. / app /: param1 /: param2, was zu / app / hallo / 123 führt).

Vielen Dank an @JasonRoyle und @daka für den Hinweis.

grreeenn
quelle
10
Sollte dies nicht dazu dienen, Abfragezeichenfolgenparameter queryParamMapnicht paramMapabzurufen?
Jason Royle
2
@ JasonRoyle Scheint, Sie sind richtig, paramMapfunktioniert nicht.
Daka
1
Diese Antwort muss gemäß den obigen Kommentaren korrigiert werden.
Daka
@ JasonRoyle, daka, du hast recht, danke, dass du darauf hingewiesen hast. Die Antwort wurde korrigiert.
Grreeenn
Perfekter Arbeitscode
Soni Kumari
17

Sie können auch HttpParams verwenden , z.

  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
quelle
1
Nur klarstellen, ich habe zwei Domains, die auf unterschiedliche Sprachwebsites verweisen. localhost / -> En, localhost /? lang = fr -> Französisch. Und ich habe Routing : path: '', redirectTo: '/list' . Der this.route.snapshot funktioniert bei mir nicht, da er redirectTo / list ist, wodurch der 'lang'-queryString entfernt wird. Aber diese Lösung funktioniert bei mir.
Ryan Huang
Als @RyanHuang habe ich das gleiche Problem. Aber diese Lösung hat bei meinem ersten Versuch funktioniert.
Gi1ber7
Finden Sie eine bessere Lösung als oben: jsonworld.com/blog/…
Soni Kumari
11
import { ParamMap, Router, ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

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

AKTUALISIEREN

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
quelle
6
Das scheint nicht genug zu sein. Ich erhalte den ActivatedRouteSnapshot, aber queryParams ist ein leeres Objekt, die Parameter sind ebenfalls leer und .queryParamMap.get ('name') gibt null zurück. Es scheint, dass ngOnInit () zu früh ist, um solche Abfrageparameter abzurufen.
Lars
Wenn Sie diese Parameter erhalten möchten, sollten Sie Ihre Route ändern.
Dmitry Grinko
Ich habe ungefähr 10 Parameter in unterschiedlicher Reihenfolge. Daher muss ich benannte Abfrageparameter verwenden. Und wie stelle ich meine Haupt-AppComponent ein, um zu erkennen, dass es 10 Parameter gibt. url / myprogram? a = 1 & b = 2 & c = 4 ... es scheint, ich habe ein Problem? Muss ich jeden Parameter an eine andere Komponente weiterleiten? Ich hoffe nicht.
Lars
Hast du das probiert? this.route.snapshot.queryParamMap
Dmitry Grinko
1
@DmitryGrinko Das Einfügen einer Entitäts-ID in eine Route ist kein schlechtes Muster. Es ermöglicht eine tiefe Verknüpfung mit einer Detailansicht.
Karl
4

Ich bin über diese Frage gestolpert, als ich nach einer ähnlichen Lösung gesucht habe, aber ich brauchte nichts wie ein Routing auf Anwendungsebene oder mehr importierte Module.

Der folgende Code eignet sich hervorragend für meine Verwendung und erfordert keine zusätzlichen Module oder Importe.

  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 Ausgänge:

param1 = hello
param2 = 123
Schilf
quelle
4

Abfrage- und Pfadparameter (Winkel 8)

Für URLs wie https://myapp.com/user/666/read?age=23 verwenden

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

AKTUALISIEREN

Wenn Sie verwenden this.router.navigate([someUrl]);und Ihre Abfrageparameter in eine someUrlZeichenfolge eingebettet sind, codiert Angular eine URL und Sie erhalten so etwas wie https://myapp.com/user/666/read%3Fage%323 - und die obige Lösung führt zu einem falschen Ergebnis ( queryParams ist leer und Pfadparameter können an den letzten Pfadparameter geklebt werden, wenn er sich am Pfadende befindet. In diesem Fall wird die Art und Weise der Navigation auf diesem

this.router.navigateByUrl(someUrl);
Kamil Kiełczewski
quelle
1
Danke @Kamil Kiełczewski, du rettest meinen Tag
Tan Nguyen
2

Leider ist die sauberste Lösung nicht die erweiterbarste Lösung. In neueren Versionen von Angular wird in den anderen Antworten vorgeschlagen, dass Sie die Abfrageparameter einfach mit ActivatedRoute Injectible und speziell mit der Snapshot-Eigenschaft abrufen können:

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

oder die Eigenschaft subscribe (wird in Fällen verwendet, in denen die Abfragezeichenfolge aktualisiert wird, z. B. beim Navigieren durch Benutzer-IDs):

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

Ich bin hier, um Ihnen zu sagen, dass diese Lösungen einen klaffenden Fehler aufweisen, der seit einiger Zeit nicht behoben wurde: https://github.com/angular/angular/issues/12157

Alles in allem besteht die einzige kugelsichere Lösung darin, gutes altes Vanille-Javascript zu verwenden. In diesem Fall habe ich einen Dienst zur URL-Manipulation erstellt:

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
quelle
2

Angular Router bietet die Methode parseUrl (url: string) , mit der die URL in UrlTree analysiert wird . Eine der Eigenschaften von UrlTree sind queryParams. So können Sie etw tun wie:

this.router.parseUrl(this.router.url).queryParams[key] || '';
Adam Michalak
quelle
Bitte posten Sie nicht mehrere identische Antworten auf verschiedene Fragen. Es gibt einige nützliche Ratschläge über diese Praxis hier
David Buck
Verwenden Sie diese Option, wenn Sie sich nicht mit URL-Änderungen befassen müssen, dh die Parameter sind bereits in der aktuellen URL verfügbar. Mach es anders als beobachtbar.
Tom
1

Wenn Sie ein leeres Routenobjekt haben, liegt dies hauptsächlich daran, dass Sie in Ihrer app.component.html keinen Router-Outlet verwenden.

Ohne dies können Sie kein aussagekräftiges Routenobjekt mit nicht leeren Unterobjekten, insbesondere params & queryParams, erhalten.

Versuchen Sie, <router-outlet><router-outlet>kurz vor dem Anruf Ihre hinzuzufügen <app-main-component></app-main-component>

Stellen Sie zuvor sicher, dass Sie Ihren Abfrageparameter im App-Routing bereit haben>, der die von der App-Komponente verwendete Klasse Route exportiert:

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

Als letztes verwende ich natürlich, um Ihren Parameter zu erhalten, this.route.snapshot.params.dynamicParamwobei dynamicParam der Name ist, der in Ihrer App-Routing-Komponente verwendet wird :)

andrea06590
quelle
1

Seien Sie vorsichtig mit Ihren Routen. Ein "redirectTo" entfernt | drop alle Abfrageparameter.

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

Ich habe meine Hauptkomponente mit Abfrageparametern wie "/ main? Param1 = a & param2 = b" aufgerufen und gehe davon aus, dass meine Abfrageparameter in der Methode "ngOnInit ()" in der Hauptkomponente eintreffen, bevor die Weiterleitung der Umleitung wirksam wird.

Das ist aber falsch. Die Umleitung erfolgt zuvor. Löschen Sie die Abfrageparameter und rufen Sie die ngOnInit () -Methode in der Hauptkomponente ohne Abfrageparameter auf.

Ich habe die dritte Zeile meiner Routen in geändert

{path: "", component: PageOneComponent},

und jetzt sind meine Abfrageparameter in den Hauptkomponenten ngOnInit und auch in der PageOneComponent zugänglich.

Lars
quelle
1

Gefunden in: Übergeordnete Komponenten erhalten leere Parameter von ActivatedRoute

Arbeitete für mich:

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
quelle
0

Ich bin gerade auf dasselbe Problem gestoßen, und die meisten Antworten hier scheinen es nur für das interne Angular-Routing zu lösen, und dann einige für Routenparameter, die nicht mit den Anforderungsparametern identisch sind.

Ich vermute, dass ich einen ähnlichen Anwendungsfall habe wie die ursprüngliche Frage von Lars.

Für mich ist der Anwendungsfall zB Empfehlungsverfolgung:

Angular läuft weiter mycoolpage.com, mit Hash-Routing, mycoolpage.comleitet also weiter mycoolpage.com/#/. Für die Überweisung sollte jedoch auch ein Link wie dieser mycoolpage.com?referrer=fooverwendet werden können. Leider entfernt Angular sofort die Anforderungsparameter und geht direkt zumycoolpage.com/#/ .

Jede Art von 'Trick' mit der Verwendung einer leeren Komponente + AuthGuard und dem Abrufen von queryParamsoderqueryParamMap hat leider bei mir nicht funktioniert. Sie waren immer leer.

Meine hackige Lösung bestand darin, dies in einem kleinen Skript zu erledigen, in index.htmldem die vollständige URL mit abgerufen wird Anforderungsparametern abgerufen wird. Ich erhalte dann den Anforderungsparameterwert über eine Zeichenfolgenmanipulation und setze ihn auf ein Fensterobjekt. Ein separater Dienst übernimmt dann das Abrufen der ID vom Fensterobjekt.

index.html Skript

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

Bedienung

declare var window: any;

@Injectable()
export class ReferrerService {

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

Einfache Lösung

 // 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
quelle
0

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

Wir können wie folgt auf den Bestellabfrageparameter zugreifen:

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

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

Es gibt auch queryParamMap, das ein Observable mit einem paramMap-Objekt zurückgibt.

Gegeben die folgende Routen-URL:

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

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

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

San Jaisy
quelle
0

Ich denke, Angular 8:

ActivatedRoute.paramswurde ersetzt durch ActivatedRoute.paramMap ActivatedRoute.queryParamswurde ersetzt durch ActivatedRoute.queryParamMap

Marvin
quelle
-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
quelle
-9

Wenn Sie keinen Angular-Router verwenden, versuchen Sie es mit Querystring . Es installieren

npm install --save querystring

zu Ihrem Projekt. Machen Sie in Ihrer Komponente so etwas

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

Das substring(1)ist notwendig, denn wenn Sie so etwas haben, lautet '/mypage?foo=bar'der Schlüsselname für?foo

Chuk Lee
quelle