Comment obtenir les paramètres de requête de l'URL dans Angular 5?

181

J'utilise angular 5.0.3, je voudrais démarrer mon application avec un tas de paramètres de requête comme /app?param1=hallo&param2=123. Chaque astuce donnée dans Comment obtenir les paramètres de requête à partir de l'URL dans Angular 2? ne fonctionne pas pour moi.

Des idées pour faire fonctionner les paramètres de requête?

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

Cette fonction privée m'aide à obtenir mes paramètres, mais je ne pense pas que ce soit la bonne manière dans le nouvel environnement Angular.

[mise à jour:] Mon application principale ressemble à

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

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    // would like to get query parameters here...
    // this.route...
  }
}
Lars
la source
Utilisez-vous des routeurs? D'où vient l'URL?
Vinod Bhavnani
Oui, ayez une ActivatedRoute. J'ai mis à jour ma question pour montrer à quoi ressemble mon composant principal.
Lars
Pouvez-vous également me montrer votre constante d'itinéraire, où vous avez configuré tous les itinéraires?
Vinod Bhavnani
const appRoutes: Routes = [{path: "one", component: PageOneComponent}, {path: "", redirectTo: "/ one", pathMatch: "full"}, {path: "**", redirectTo: "/ une"} ]; Ma constante Route. Je voudrais obtenir tous les paramètres de l'App Store principal dans un DTO, puis accéder à une autre page. La navigation de page fonctionne comme prévu, mais j'obtiens les paramètres de requête à main uniquement par ma fonction 'getQueryParameter'. Je me rends compte dans votre question qu'il existe quelque chose que j'ai oublié. Dois-je marquer mes noms de paramètres n'importe où?
Lars
Oui, dans vos itinéraires, vous devez également définir les paramètres. Si vous consultez les documents de routage sur angular.io, vous pouvez voir comment ils définissent les paramètres sur un itinéraire particulier. Quelque chose comme ceci {chemin: 'abc /: param1', component: componentClassName}
Vinod Bhavnani

Réponses:

239

Dans Angular 5, les paramètres de requête sont accessibles en vous abonnant à this.route.queryParams.

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

tandis que les variables de chemin d'accès sont accessibles par this.route.snapshot.params

Exemple: /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
la source
15
Selon la documentation Angular 6 , l'utilisation d'ActivatedRoute.queryParams et de .params est déconseillée et pourrait être déconseillée dans les versions futures; voir la mise à jour ici
grreeenn
1
@ShubhenduVaid explique pourquoi, ils devraient utiliser le ngOnInit au lieu du constructeur. La meilleure pratique sera d'utiliser RxJS observable, puis d'utiliser une approche déclarative lorsque vous travaillez avec des observables, puis d'utiliser async sur le html
coderpatomx
118

C'est la solution la plus propre pour moi

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
la source
Ceci est utile, merci. Depuis angular 6.0.8, j'utilise ceci et cela fonctionne pour moi: this.route.snapshot.queryParams ["firstParamKey"]
fluidguid
2
Cela fonctionne pour moi dans Angular8. this.route.snapshot.queryParamMap fonctionne. this.route.snapshot.paramMap ne fonctionne pas pour moi.
Romeo Profijt
89

Je sais que OP a demandé une solution Angular 5, mais encore pour vous tous qui tombez sur cette question pour les versions angulaires plus récentes (6+). En citant les documents , concernant ActivatedRoute.queryParams (sur lesquels la plupart des autres réponses sont basées):

Deux propriétés plus anciennes sont toujours disponibles. Ils sont moins capables que leurs remplaçants, déconseillés et pourraient être déconseillés dans une future version Angular.

params - Un observable qui contient les paramètres obligatoires et facultatifs spécifiques à l'itinéraire. Utilisez plutôt paramMap.

queryParams - Un observable qui contient les paramètres de requête disponibles pour tous les itinéraires. Utilisez plutôt queryParamMap.

Selon la documentation , le moyen simple d'obtenir les paramètres de requête ressemblerait à ceci:

constructor(private route: ActivatedRoute) { }

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

Pour des méthodes plus avancées (par exemple la réutilisation avancée des composants), consultez ce chapitre Docs.

ÉDITER:

Comme indiqué correctement dans les commentaires ci-dessous, cette réponse est fausse - du moins pour le cas spécifié par OP.

OP demande d'obtenir les paramètres de requête globaux (/ app? Param1 = hallo & param2 = 123); dans ce cas, vous devez utiliser queryParamMap (comme dans @ dapperdan1985 answer).

paramMap, d'autre part, est utilisé sur des paramètres spécifiques à la route (par exemple / app /: param1 /: param2, ce qui donne / app / hallo / 123).

Merci à @JasonRoyle et @daka pour l'avoir signalé.

Grreeenn
la source
10
Cela ne devrait-il pas être utilisé pour queryParamMapne paramMappas récupérer les paramètres de chaîne de requête?
Jason Royle
2
@JasonRoyle Semble que vous avez raison, paramMapne fonctionne pas.
daka
1
Cette réponse doit être corrigée conformément aux commentaires ci-dessus.
daka
@JasonRoyle, daka, tu as raison, merci de l'avoir signalé. Correction de la réponse.
grreeenn
Code de travail parfait trouvé: jsonworld.com/blog/…
Soni Kumari
17

Vous pouvez également utiliser HttpParams , tels que:

  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
la source
1
Précisez simplement, j'ai deux domaines pointant vers un site de langue différente. localhost / -> En, localhost /? lang = fr -> Français. Et je routage: path: '', redirectTo: '/list' . Le this.route.snapshot ne fonctionne pas pour moi car il redirige vers / list qui élimine le queryString 'lang'. Mais cette solution fonctionne pour moi.
Ryan Huang
En tant que @RyanHuang, j'ai un peu le même problème. Mais cette solution a fonctionné lors de mon premier essai.
Gi1ber7
Trouvez une meilleure solution que ci-dessus: jsonworld.com/blog/…
Soni Kumari
11
import { ParamMap, Router, ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

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

METTRE À JOUR

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
la source
6
cela semble ne pas suffire, j'obtiens le ActivatedRouteSnapshot mais queryParams est un objet vide, les paramètres sont également vides et .queryParamMap.get ('nom') renvoie null. Il semble que ngOnInit () soit trop tôt pour obtenir de tels paramètres de requête.
Lars
en fait, si vous voulez obtenir ces paramètres, vous devez changer votre itinéraire.
Dmitry Grinko
J'ai environ 10 paramètres dans un ordre différent. Par conséquent, je dois utiliser des paramètres de requête nommés. Et comment configurer mon AppComponent principal pour réaliser qu'il y a 10 paramètres. url / monprogramme? a = 1 & b = 2 & c = 4 ... ça coute j'ai un problème? Dois-je acheminer chaque paramètre vers un autre composant? J'espère que non.
Lars
Avez-vous essayé celui-ci? this.route.snapshot.queryParamMap
Dmitry Grinko
1
@DmitryGrinko mettre un identifiant d'entité dans une route n'est pas un mauvais modèle, cela permet un lien profond vers une vue détaillée.
Karl
5

Paramètres de requête et de chemin (Angular 8)

Pour une URL comme https://myapp.com/user/666/read?age=23, utilisez

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

METTRE À JOUR

Dans le cas où vous utilisez this.router.navigate([someUrl]);et que vos paramètres de requête sont incorporés dans une someUrlchaîne, angular encode une URL et vous obtenez quelque chose comme ceci https://myapp.com/user/666/read%3Fage%323 - et la solution ci-dessus donnera un résultat erroné ( queryParams sera vide et les paramètres de chemin peuvent être collés au dernier paramètre de chemin s'il se trouve à l'extrémité du chemin). Dans ce cas, modifiez le mode de navigation pour

this.router.navigateByUrl(someUrl);
Kamil Kiełczewski
la source
1
Merci @Kamil Kiełczewski, vous sauvez ma journée
Tan Nguyen
4

Je suis tombé sur cette question lorsque je cherchais une solution similaire, mais je n'avais besoin de rien comme un routage complet au niveau de l'application ou plus de modules importés.

Le code suivant fonctionne très bien pour mon utilisation et ne nécessite aucun module ou importation supplémentaire.

  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 les sorties:

param1 = hello
param2 = 123
Roseau
la source
3

Angular Router fournit la méthode parseUrl (url: string) qui analyse l'URL en UrlTree . Une des propriétés d'UrlTree est queryParams. Donc vous pouvez faire qc comme:

this.router.parseUrl(this.router.url).queryParams[key] || '';
Adam Michalak
la source
Veuillez ne pas publier plusieurs réponses identiques à des questions différentes. Il y a quelques conseils utiles sur cette pratique ici
David Buck
Utilisez cette option si vous n'avez pas besoin de gérer les modifications d'URL, c'est-à-dire que les paramètres sont déjà disponibles dans l'URL actuelle. Sinon, faites-le de la manière observable.
tom
2

Malheureusement, la solution la plus propre n'est pas la solution la plus extensible. Dans les versions récentes d'Angular, il est suggéré dans les autres réponses que vous pouvez facilement obtenir les paramètres de requête en utilisant ActivatedRoute Injectible et en utilisant spécifiquement la propriété snapshot:

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

ou la propriété subscribe (utilisée dans les cas où la chaîne de requête sera mise à jour, par exemple en naviguant dans les identifiants utilisateur):

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

Je suis ici pour vous dire que ces solutions ont un défaut béant qui n'a pas été résolu depuis un certain temps: https://github.com/angular/angular/issues/12157

Dans l'ensemble, la seule solution à toute épreuve est d'utiliser du bon vieux javascript vanille. Dans ce cas, j'ai créé un service de manipulation d'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
la source
1

Lorsque vous avez un objet route vide, c'est principalement dû au fait que vous n'utilisez pas de sortie de routeur dans votre app.component.html.

Sans cela, vous ne pourrez pas obtenir un objet route significatif avec des sous-objets non vides, en particulier les paramètres et queryParams.

Essayez d'ajouter <router-outlet><router-outlet> juste avant d'appeler votre <app-main-component></app-main-component>

Avant cela, assurez-vous que votre paramètre de requête est prêt dans app-routing> qui exporte la classe Route utilisée par le composant App:

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

Dernière chose bien sûr, pour obtenir votre paramètre, j'utilise personnellement this.route.snapshot.params.dynamicParamoù dynamicParam est le nom utilisé dans votre composant de routage d'application :)

andrea06590
la source
1

Soyez prudent avec vos itinéraires. Un "redirectTo" supprimera | supprimera tout paramètre de requête.

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

J'ai appelé mon composant principal avec des paramètres de requête comme "/ main? Param1 = a & param2 = b et je suppose que mes paramètres de requête arrivent dans la méthode" ngOnInit () "dans le composant principal avant que la redirection ne prenne effet.

Mais c'est faux. La redirection viendra avant, supprimez les paramètres de requête et appelez la méthode ngOnInit () dans le composant principal sans paramètres de requête.

J'ai changé la troisième ligne de mes itinéraires en

{path: "", component: PageOneComponent},

et maintenant mes paramètres de requête sont accessibles dans les principaux composants ngOnInit et aussi dans le PageOneComponent.

Lars
la source
1

Trouvé dans: les composants parents obtiennent des paramètres vides d'ActivatedRoute

A travaillé pour moi:

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
la source
0

Je suis juste tombé sur le même problème et la plupart des réponses ici semblent ne le résoudre que pour le routage interne angulaire, puis certaines d'entre elles pour les paramètres d'itinéraire qui ne sont pas les mêmes que les paramètres de requête.

Je suppose que j'ai un cas d'utilisation similaire à la question initiale de Lars.

Pour moi, le cas d'utilisation est par exemple le suivi des références:

Angular en cours d'exécution mycoolpage.com, avec routage de hachage, mycoolpage.comredirige donc vers mycoolpage.com/#/. Pour référence, cependant, un lien tel que mycoolpage.com?referrer=foodevrait également être utilisable. Malheureusement, Angular supprime immédiatement les paramètres de la requête, allant directement à mycoolpage.com/#/.

Toute sorte de «truc» avec l'utilisation d'un composant vide + AuthGuard et obtenir queryParamsou queryParamMapn'a malheureusement pas fonctionné pour moi. Ils étaient toujours vides.

Ma solution hacky a fini par être de gérer cela dans un petit script dans index.htmllequel obtient l'URL complète, avec paramètres de requête. J'obtiens ensuite la valeur du paramètre de la demande via la manipulation de la chaîne et je la place sur l'objet window. Un service distinct gère ensuite l'obtention de l'ID de l'objet window.

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

Un service

declare var window: any;

@Injectable()
export class ReferrerService {

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

Solution 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
la source
0

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

Nous pouvons accéder au paramètre de requête de commande comme ceci:

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

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

Il y a aussi queryParamMap, qui retourne une observable avec un objet paramMap.

Compte tenu de l'URL de la route suivante:

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

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

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

San Jaisy
la source
0

À, je pense que Angular 8:

ActivatedRoute.paramsa été remplacé par ActivatedRoute.paramMap ActivatedRoute.queryParamsa été remplacé par ActivatedRoute.queryParamMap

Marvin
la source
-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);

 });

  }
Islam Kaji
la source
-9

Si vous n'utilisez pas de routeur angulaire, essayez de lancer une requête . Installez-le

npm install --save querystring

à votre projet. Dans votre composant, faites quelque chose comme ça

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

Le substring(1)est nécessaire car si vous avez quelque chose comme ça, '/mypage?foo=bar'le nom de la clé sera?foo

Chuk Lee
la source