Bagaimana cara mendapatkan parameter kueri dari URL di Angular 5?

181

Saya menggunakan angular 5.0.3, saya ingin memulai aplikasi saya dengan sekelompok parameter permintaan seperti /app?param1=hallo&param2=123. Setiap tip yang diberikan dalam Bagaimana cara mendapatkan kueri dari url di Angular 2? tidak bekerja untuk saya.

Adakah gagasan bagaimana agar parameter kueri berfungsi?

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

Fungsi pribadi ini membantu saya untuk mendapatkan parameter saya, tapi saya rasa itu bukan cara yang tepat di lingkungan Angular baru.

[perbarui:] Aplikasi utama saya terlihat seperti

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

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    // would like to get query parameters here...
    // this.route...
  }
}
Lars
sumber
Apakah Anda menggunakan router? Dari mana URL berasal?
Vinod Bhavnani
Ya, miliki ActivatedRoute. Saya memperbarui pertanyaan saya untuk menunjukkan bagaimana komponen utama saya terlihat.
Lars
Bisakah Anda juga menunjukkan kepada saya konstanta rute Anda, di mana Anda telah mengatur semua rute?
Vinod Bhavnani
const appRoutes: Routes = [{path: "one", komponen: PageOneComponent}, {path: "", redirectTo: "/ one", pathMatch: "full"}, {path: "**", redirectTo: "/ satu"} ]; Rute saya konstan. Saya ingin mendapatkan semua parameter di toko aplikasi utama itu di DTO, lalu arahkan ke halaman lain. Navigasi halaman berfungsi seperti yang diharapkan, tapi saya mendapatkan parameter kueri hanya dengan fungsi 'getQueryParameter' saya. Saya menyadari dalam pertanyaan Anda bahwa ada sesuatu yang telah saya lupakan. Apakah saya perlu menandai nama parameter saya di mana saja?
Lars
Ya, di rute Anda, Anda perlu menentukan parameter juga. Jika Anda memeriksa dokumen perutean pada angular.io, Anda dapat melihat bagaimana mereka menentukan parameter pada rute tertentu. Sesuatu seperti {path: 'abc /: param1' ini, komponen: componentClassName}
Vinod Bhavnani

Jawaban:

239

Di Angular 5, params kueri diakses dengan berlangganan this.route.queryParams.

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

sedangkan, variabel path diakses oleh this.route.snapshot.params

Contoh: /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
sumber
15
Menurut Angular 6 docs , penggunaan ActivatedRoute.queryParams dan .params tidak disarankan dan mungkin tidak digunakan lagi di versi mendatang; lihat pembaruan di sini
grreeenn
1
@ShubhenduVaid menjelaskan alasannya, mereka harus menggunakan ngOnInit alih-alih konstruktor. Praktik terbaik akan menggunakan RxJS yang dapat diamati, kemudian menggunakan pendekatan deklaratif ketika bekerja dengan yang dapat diobservasi, kemudian menggunakan async pada html
coderpatomx
118

Ini solusi terbersih untuk saya

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
sumber
Ini membantu, terima kasih. Pada sudut 6.0.8, saya menggunakan ini dan berfungsi untuk saya: this.route.snapshot.queryParams ["firstParamKey"]
fluidguid
2
Ini bekerja untuk saya di Angular8. this.route.snapshot.queryParamMap berfungsi. this.route.snapshot.paramMap tidak berfungsi untuk saya.
Romeo Profijt
89

Saya tahu bahwa OP meminta solusi Angular 5, tetapi bagi Anda yang tersandung pada pertanyaan ini untuk versi Angular (6+) yang lebih baru. Mengutip Dokumen , mengenai ActivatedRoute.queryParams (yang menjadi dasar sebagian besar jawaban lain):

Dua properti lama masih tersedia. Mereka kurang mampu daripada pengganti mereka, berkecil hati, dan mungkin usang dalam versi Angular masa depan.

params - Suatu Observable yang berisi parameter yang diperlukan dan opsional khusus untuk rute. Gunakan paramMap sebagai gantinya.

queryParams - Suatu Observable yang berisi parameter kueri yang tersedia untuk semua rute. Gunakan queryParamMap sebagai gantinya.

Menurut Documents , cara sederhana untuk mendapatkan params kueri akan terlihat seperti ini:

constructor(private route: ActivatedRoute) { }

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

Untuk cara yang lebih lanjut (misalnya penggunaan ulang komponen lanjutan) lihat bab Documents ini .

EDIT:

Seperti yang dinyatakan dengan benar dalam komentar di bawah, jawaban ini salah - setidaknya untuk kasus yang ditentukan oleh OP.

OP meminta untuk mendapatkan parameter kueri global (/ app? Param1 = hallo & param2 = 123); dalam hal ini Anda harus menggunakan queryParamMap (sama seperti pada jawaban @ dapperdan1985).

paramMap, di sisi lain, digunakan pada parameter khusus untuk rute (misalnya / app /: param1 /: param2, menghasilkan / app / hallo / 123).

Terima kasih kepada @JasonRoyle dan @daka karena telah menunjukkannya.

Grreeenn
sumber
10
Bukankah ini harus digunakan untuk queryParamMaptidak paramMapmengambil parameter string kueri?
Jason Royle
2
@JasonRoyle Sepertinya Anda benar, paramMaptidak berfungsi.
daka
1
Jawaban ini perlu dikoreksi sesuai komentar di atas.
daka
@JasonRoyle, daka, Anda benar, terima kasih telah menunjukkannya. Memperbaiki jawabannya.
Grreeenn
Ditemukan kode kerja yang sempurna: jsonworld.com/blog/…
Soni Kumari
17

Anda juga dapat Menggunakan HttpParams , seperti:

  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
sumber
1
Hanya memperjelas, saya memiliki dua domain yang menunjuk ke situs bahasa yang berbeda. localhost / -> En, localhost /? lang = fr -> Prancis. Dan saya telah Routing: path: '', redirectTo: '/list' . The this.route.snapshot tidak berfungsi untuk saya karena redirectTo / daftar yang menghilangkan queryString 'lang'. Tetapi solusi ini bekerja untuk saya.
Ryan Huang
Sebagai @RyanHuang, saya memiliki masalah yang sama. Tetapi solusi ini berhasil pada percobaan pertama saya.
Gi1ber7
Temukan solusi yang lebih baik daripada di atas: jsonworld.com/blog/…
Soni Kumari
11
import { ParamMap, Router, ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

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

MEMPERBARUI

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
sumber
6
yang tampaknya tidak cukup, saya mendapatkan ActivatedRouteSnapshot tetapi queryParams adalah objek kosong, params juga kosong dan .queryParamMap.get ('name') mengembalikan nol. Tampaknya ngOnInit () terlalu dini untuk mendapatkan parameter kueri tersebut.
Lars
sebenarnya jika Anda ingin mendapatkan params ini, Anda harus mengubah rute Anda.
Dmitry Grinko
Saya memiliki sekitar 10 parameter dalam urutan berbeda. Karena itu saya harus menggunakan parameter kueri bernama. Dan bagaimana cara mengatur AppComponent utama saya untuk menyadari bahwa ada 10 parameter. url / myprogram? a = 1 & b = 2 & c = 4 ... sepertinya saya punya masalah? Apakah saya perlu merutekan setiap parameter ke komponen lain? Saya harap tidak.
Lars
Apakah Anda mencoba yang ini? this.route.snapshot.queryParamMap
Dmitry Grinko
1
@DmitryGrinko menempatkan entitas entitas ke dalam rute bukan pola yang buruk, memungkinkan tautan dalam ke tampilan detail.
Karl
5

Params Kueri dan Path (Sudut 8)

Untuk url seperti https://myapp.com/user/666/read?age=23 gunakan

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

MEMPERBARUI

Dalam kasus ketika Anda menggunakan this.router.navigate([someUrl]);dan parameter kueri Anda tertanam dalam someUrlstring maka sudut menyandikan URL dan Anda mendapatkan sesuatu seperti ini https://myapp.com/user/666/read%3Fage%323 - dan solusi di atas akan memberikan hasil yang salah ( queryParams akan kosong, dan params jalur dapat direkatkan ke param path terakhir jika berada di ujung path). Dalam hal ini ubah cara navigasi ke ini

this.router.navigateByUrl(someUrl);
Kamil Kiełczewski
sumber
1
Terima kasih @Kamil Kiełczewski, Anda menyelamatkan hari saya
Tan Nguyen
4

Tersandung di pertanyaan ini ketika saya sedang mencari solusi yang sama tetapi saya tidak memerlukan apa pun seperti perutean level aplikasi penuh atau lebih banyak modul yang diimpor.

Kode berikut berfungsi baik untuk saya gunakan dan tidak memerlukan modul atau impor tambahan.

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

param1 = hello
param2 = 123
Reed
sumber
3

Angular Router menyediakan metode parseUrl (url: string) yang mem-parsing url ke dalam UrlTree . Salah satu properti dari UrlTree adalah queryParams. Jadi Anda bisa melakukan sth seperti:

this.router.parseUrl(this.router.url).queryParams[key] || '';
Adam Michalak
sumber
Tolong jangan posting beberapa jawaban identik untuk pertanyaan yang berbeda. Ada beberapa saran berguna tentang praktik ini di sini
David Buck
Gunakan ini jika Anda tidak perlu berurusan dengan perubahan URL, yaitu parameter sudah tersedia di URL saat ini. Lakukan dengan cara yang bisa diamati sebaliknya.
tom
2

Sayangnya, solusi terbersih bukanlah solusi yang paling dapat dikembangkan. Dalam versi terbaru dari Angular, disarankan di jawaban lain bahwa Anda dapat dengan mudah mendapatkan parameter permintaan menggunakan ActivatedRoute Injectible dan secara khusus memanfaatkan properti snapshot:

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

atau properti berlangganan (digunakan dalam kasus di mana string kueri akan diperbarui, misalnya menavigasi melalui id pengguna):

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

Saya di sini untuk memberi tahu Anda bahwa solusi ini memiliki kelemahan menganga yang belum diselesaikan untuk beberapa waktu: https://github.com/angular/angular/issues/12157

Semua dalam semua, satu-satunya solusi bukti peluru adalah menggunakan javascript vanilla tua yang baik. Dalam hal ini, saya membuat layanan untuk manipulasi 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
sumber
1

Ketika Anda memiliki objek rute kosong, ini terutama disebabkan oleh fakta bahwa Anda tidak menggunakan outlet router di app.component.html Anda.

Tanpa ini, Anda tidak akan bisa mendapatkan objek rute yang bermakna dengan subObject tidak kosong, terutama params & queryParams.

Coba tambahkan <router-outlet><router-outlet>sesaat sebelum menelepon <app-main-component></app-main-component>

Sebelum itu, pastikan Anda memiliki param kueri Anda siap dalam perutean aplikasi> yang mengekspor Rute kelas yang digunakan oleh komponen Aplikasi:

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

Hal terakhir tentu saja, untuk mendapatkan param Anda, saya menggunakan di this.route.snapshot.params.dynamicParammana dynamicParam adalah nama yang digunakan dalam komponen perutean aplikasi Anda :)

andrea06590
sumber
1

Hati-hati dengan rute Anda. "RedirectTo" akan menghapus | drop parameter kueri apa pun.

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

Saya menyebut komponen utama saya dengan parameter kueri seperti "/ main? Param1 = a & param2 = b dan menganggap bahwa parameter kueri saya tiba di metode" ngOnInit () "di komponen utama sebelum penerusan pengalihan berlaku.

Tapi ini salah. Redirect akan datang sebelumnya, membuang parameter kueri dan memanggil metode ngOnInit () di komponen utama tanpa parameter kueri.

Saya mengubah jalur ketiga dari rute saya ke

{path: "", component: PageOneComponent},

dan sekarang parameter kueri saya dapat diakses di komponen utama ngOnInit dan juga di PageOneComponent.

Lars
sumber
1

Ditemukan dalam: Komponen induk mendapat Params kosong dari ActivatedRoute

Bekerja untuk saya:

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

Hanya menemukan masalah yang sama dan sebagian besar jawaban di sini tampaknya hanya menyelesaikannya untuk routing internal Angular, dan kemudian beberapa dari mereka untuk parameter rute yang tidak sama dengan parameter permintaan.

Saya menduga bahwa saya memiliki kasus penggunaan yang mirip dengan pertanyaan asli oleh Lars.

Bagi saya kasus penggunaannya adalah misalnya pelacakan referensi:

Sudut berjalan mycoolpage.com, dengan perutean hash, jadi mycoolpage.comdialihkan ke mycoolpage.com/#/. Namun untuk rujukan, tautan seperti mycoolpage.com?referrer=fooitu juga harus dapat digunakan. Sayangnya, Angular segera menghapus parameter permintaan, langsung ke mycoolpage.com/#/.

Segala macam 'trik' dengan menggunakan komponen kosong + AuthGuard dan mendapatkan queryParamsatau queryParamMaptidak, sayangnya, tidak berhasil untuk saya. Mereka selalu kosong.

Solusi hacky saya akhirnya menangani ini dalam skrip kecil di index.htmlmana mendapatkan URL lengkap, dengan parameter permintaan. Saya kemudian mendapatkan nilai param permintaan melalui manipulasi string dan meletakkannya di objek jendela. Layanan terpisah kemudian menangani mendapatkan id dari objek jendela.

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

Layanan

declare var window: any;

@Injectable()
export class ReferrerService {

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

Solusi Sederhana

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

http: // localhost: 4200 / produk? order = populer

Kami dapat mengakses param kueri pesanan seperti ini:

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

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

Ada juga queryParamMap, yang mengembalikan objek yang dapat diamati dengan paramMap.

Diberikan URL rute berikut:

http: // localhost: 4200 / produk? order = populer & filter = baru

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

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

San Jaisy
sumber
0

Di, saya pikir Angular 8:

ActivatedRoute.paramstelah digantikan oleh ActivatedRoute.paramMap ActivatedRoute.queryParamstelah digantikan oleh ActivatedRoute.queryParamMap

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

Jika Anda tidak menggunakan router Angular coba, querystring . Pasang itu

npm install --save querystring

untuk proyek Anda. Dalam komponen Anda, lakukan sesuatu seperti ini

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

Ini substring(1)diperlukan karena jika Anda memiliki sesuatu seperti ini '/mypage?foo=bar'maka nama kuncinya adalah?foo

Chuk Lee
sumber