Angular 5でURLからクエリパラメータを取得するにはどうすればよいですか?


180

Angular 5.0.3を使用していますが、のような一連のクエリパラメータでアプリケーションを起動したいと思います/app?param1=hallo&param2=123Angular 2でURLからクエリパラメータを取得する方法で与えられたすべてのヒント私にはうまくいきません。

クエリパラメータを機能させる方法はありますか?

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

このプライベート関数はパラメーターを取得するのに役立ちますが、新しいAngular環境では適切な方法ではないと思います。

[更新:]私のメインアプリは次のようになります

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

  constructor(private route: ActivatedRoute) {}

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

ルーターを使用していますか?URLはどこから来ていますか?
Vinod Bhavnani 2017年

はい、ActivatedRouteを持っています。質問を更新して、メインコンポーネントの外観を示しました。
Lars、

すべてのルートを設定したルート定数も教えていただけますか?
Vinod Bhavnani 2017年

const appRoutes:Routes = [{path: "one"、component:PageOneComponent}、{path: ""、redirectTo: "/ one"、pathMatch: "full"}、{path: "**"、redirectTo: "/ 1"} ]; 私のルート定数。メインアプリのすべてのパラメーターをDTOに保存してから、他のページに移動したいと思います。ページナビゲーションは期待どおりに機能しますが、メインでクエリパラメータを取得するには、「getQueryParameter」関数を使用するだけです。あなたの質問で、私が忘れていたものがあることに気づきました。パラメータ名をどこかにマークする必要がありますか?
Lars

はい、ルートでは、パラメーターも定義する必要があります。angular.ioのルーティングドキュメントを確認すると、特定のルートでパラメーターを定義する方法を確認できます。次のようなもの{path: 'abc /:param1'、component:componentClassName}
Vinod Bhavnani

回答:


237

Angular 5では、クエリパラメータはにサブスクライブすることでアクセスされますthis.route.queryParams

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

一方、パス変数は this.route.snapshot.params

例: /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
Angular 6のドキュメントによると、ActivatedRoute.queryParamsと.paramsの使用は推奨されておらず、将来のバージョンでは非推奨になる可能性があります。ここで
grreeenn

1
@ShubhenduVaidが理由を説明します。コンストラクタの代わりにngOnInitを使用する必要があります。ベストプラクティスは、RxJSオブザーバブルを使用し、オブザーバブルを操作するときに宣言的アプローチを使用し、htmlで非同期を使用する
coderpatomx

118

これは私にとって最もクリーンなソリューションです

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

これは役に立ちます。ありがとう。angular 6.0.8以降、私はこれを使用していて、私のために機能します:this.route.snapshot.queryParams ["firstParamKey"]
fluidguid

2
これは私にとってAngular8で機能します。this.route.snapshot.queryParamMapが機能します。this.route.snapshot.paramMapが機能しません。
Romeo Profijt

89

OPがAngular 5ソリューションを要求したことは知っていますが、新しい(6+)Angularバージョンについてこの質問に出くわした皆さんすべてのためにです。ドキュメントの引用、ActivatedRoute.queryParams(他のほとんどの回答はこれに基づいています)に関して:

2つの古いプロパティがまだ利用可能です。それらは代替品よりも機能低く、推奨されおらず、廃止される可能性があります。また、将来のAngularバージョンでに。

params —ルートに固有の必須およびオプションのパラメーターを含むObservable。代わりにparamMapを使用してください。

queryParams —すべてのルートで使用可能なクエリパラメータを含むObservable。代わりにqueryParamMapを使用してください。

Docsによると、クエリパラメータを取得する簡単な方法は次のようになります。

constructor(private route: ActivatedRoute) { }

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

より高度な方法(高度なコンポーネントの再利用など)については、こちらを参照してくださいドキュメントの章を。

編集:

以下のコメントで正しく述べられているように、この答えは間違っています-少なくともOPによって指定されたケースでは。

OPは、グローバルクエリパラメータ(/ app?param1 = hallo&param2 = 123)を取得するよう要求します。この場合は、queryParamMapを使用する必要があります(@ dapperdan1985の回答と同様)。

一方、paramMapはルートに固有のパラメーターで使用されます(例:/ app /:param1 /:param2、結果は/ app / hallo / 123)。

指摘してくれた@JasonRoyleと@dakaに感謝します。


10
これqueryParamMapparamMap、クエリ文字列パラメーターを取得しないために使用するべきではありませんか?
Jason Royle

2
@JasonRoyleあなたは正しいようです、paramMap動作しません。
ダカ

1
この回答は、上記のコメントに従って修正する必要があります。
ダカ

@JasonRoyle、ダカ、そうだね、指摘してくれてありがとう。答えを修正しました。
grreeenn

見つかった完璧な作業コード:jsonworld.com/blog/...
曽爾クマリ

17

次のようなHttpParamsを使用することもできます。

  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
明確に言うと、2つのドメインが異なる言語のサイトをポイントしています。localhost /-> En、localhost /?lang = fr->フランス語。そして私はルーティングを持っています:path: '', redirectTo: '/list' 。this.route.snapshotは、私にとっては機能しません。redirectTo/ listは、 'lang' queryStringを排除するためです。しかし、この解決策は私にとってはうまくいきます。
Ryan Huang

@RyanHuangと同じ問題があります。しかし、この解決策は私の最初の試験で機能しました。
Gi1ber7

:上記より良いソリューションの検索jsonworld.com/blog/...
曽爾クマリ

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

constructor(private route: ActivatedRoute) {}

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

更新

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
それは十分ではないようです、私はActivatedRouteSnapshotを取得しますが、queryParamsは空のオブジェクトであり、paramsも空で、.queryParamMap.get( 'name')はnullを返します。ngOnInit()は、そのようなクエリパラメータを取得するには早すぎるようです。
Lars

実際にこのパラメータを取得したい場合は、ルートを変更する必要があります。
Dmitry Grinko 2017年

約10個のパラメーターが異なる順序で丸められています。したがって、名前付きクエリパラメータを使用する必要があります。また、メインのAppComponentを設定して、10個のパラメーターがあることを確認するにはどうすればよいですか。url / myprogram?a = 1&b = 2&c = 4 ...問題があるように見えますか?すべてのパラメーターを他のコンポーネントにルーティングする必要がありますか?私は望みません。
Lars、

これ試してみましたか?this.route.snapshot.queryParamMap
Dmitry Grinko 2017年

1
エンティティIDをルートに入れる@DmitryGrinkoは悪いパターンではなく、詳細ビューへのディープリンクを可能にします。
Karl、


4

同様の解決策を探していたときにこの質問に出くわしましたが、完全なアプリケーションレベルのルーティングやインポートされたモジュールのようなものは必要ありませんでした。

次のコードは私の使用に最適で、追加のモジュールやインポートは必要ありません。

  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 出力:

param1 = hello
param2 = 123

4

クエリとパスのパラメーター(Angular 8)

https://myapp.com/user/666/read?age=23のようなURLの場合

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

更新

使用this.router.navigate([someUrl]);し、クエリパラメータがsomeUrl文字列に埋め込まれている場合、URLが角度エンコードされ、次のようなものが得られますhttps://myapp.com/user/666/read%3Fage%323-上記のソリューションでは、間違った結果が得られます( queryParamsは空になり、パスの最後にある場合、パスのパラメーターを最後のパスのパラメーターに接着できます)。この場合、ナビゲーションの方法をこれに変更します

this.router.navigateByUrl(someUrl);

1
@KamilKiełczewskiに感謝します。私の日を節約してください
Tan Nguyen

2

残念ながら、最もクリーンなソリューションは、最も拡張可能なソリューションではありません。Angularの最近のバージョンでは、他の回答で、ActivatedRoute Injectibleを使用して、特にスナップショットプロパティのいずれかを利用して、クエリパラメーターを簡単に取得できることが推奨されています。

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

またはsubscribeプロパティ(クエリ文字列が更新される場合に使用されます(例:ユーザーIDのナビゲート):

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

これらのソリューションには、しばらく解決されていない大きな欠陥があることをお伝えします。 https //github.com/angular/angular/issues/12157

全体として、唯一の防弾ソリューションは古き良きバニラJavaScriptを使用することです。この場合、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']
        }
    }
}

2

角度のルータは、方法を提供する:parseURLを(文字列のURL)にURLを解析しUrlTreeを。UrlTreeのプロパティの1つはqueryParamsです。したがって、次のように実行できます。

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

異なる質問に複数の同じ答えを投稿しないでください。この実践についてのいくつかの有用なアドバイスがあります
デビッドバック

URLの変更を処理する必要がない場合、つまり、現在のURLでパラメーターがすでに使用可能である場合に、これを使用します。それ以外の場合は、観察可能な方法で行います。
トム

1

空のルートオブジェクトがある場合は、主にapp.component.htmlでルーターアウトレットを使用していないことが原因です。

これがないと、空でないサブオブジェクト、特にparamsとqueryParamsを持つ意味のあるルートオブジェクトを取得できません。

<router-outlet><router-outlet>呼び出す直前に追加してみてください <app-main-component></app-main-component>

その前に、app-routingでクエリパラメータの準備ができていることを確認してください。これにより、Appコンポーネントで使用されるクラスRouteがエクスポートされます。

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

もちろん、最後this.route.snapshot.params.dynamicParamにパラメーターを取得するために、私はdynamicParamがアプリのルーティングコンポーネントで使用される名前であるところを個人的に使用します:)


1

ルートには注意してください。「redirectTo」は、クエリパラメータを削除|ドロップします。

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

「/ main?param1 = a&param2 = b」のようなクエリパラメータでメインコンポーネントを呼び出し、リダイレクト転送が有効になる前に、クエリパラメータがメインコンポーネントの「ngOnInit()」メソッドに到着すると想定します。

しかし、これは間違っています。リダイレクトは以前に行われ、クエリパラメータを削除し、クエリパラメータなしでメインコンポーネントのngOnInit()メソッドを呼び出します。

ルートの3行目を

{path: "", component: PageOneComponent},

そして今、私のクエリパラメーターはメインコンポーネントngOnInitとPageOneComponentでもアクセス可能です。


1

見つかった場所:親コンポーネントがActivatedRouteから空のパラメーターを取得

私のために働いた:

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

同じ問題に遭遇しただけで、ここでのほとんどの回答はAngular内部ルーティングの場合のみ問題を解決し、その一部はリクエストパラメータとは異なるルートパラメータの場合に解決されるようです。

Larsによる元の質問と同様のユースケースがあると思います。

私にとってのユースケースは、例えば紹介追跡です:

Angularはmycoolpage.com、ハッシュルーティングを使用してで実行されているため、にmycoolpage.comリダイレクトされmycoolpage.com/#/ます。ただし、紹介のためになどのリンクmycoolpage.com?referrer=fooも使用できる必要があります。残念ながら、Angularはリクエストパラメータをすぐに取り除き、直接mycoolpage.com/#/ます。

空のコンポーネント+ AuthGuardを使用して取得queryParamsまたは取得するあらゆる種類の「トリック」queryParamMap、私にとっては残念ながら、ない仕事をしました。彼らはいつも空っぽでした。

私のハックな解決策はリクエストパラメータを使用index.htmlて完全なURLを取得する小さなスクリプトでこれを処理することでした。次に、文字列操作を介してリクエストパラメータ値を取得し、ウィンドウオブジェクトに設定します。次に、個別のサービスがウィンドウオブジェクトからのIDの取得を処理します。

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

サービス

declare var window: any;

@Injectable()
export class ReferrerService {

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

0

シンプルなソリューション

 // 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 / products?order = popular

次のように注文クエリパラメータにアクセスできます。

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

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

paramMapオブジェクトでオブザーバブルを返すqueryParamMapもあります。

次のルートURLがあるとします。

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

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

ソース-https://alligator.io/angular/query-parameters/


0

で、私はAngular 8を思います:

ActivatedRoute.paramsに置き換えられましたActivatedRoute.paramMap ActivatedRoute.queryParamsに置き換えられました 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

Angularルーターを使用していない場合は、querystringを試してください。インストールする

npm install --save querystring

あなたのプロジェクトに。あなたのコンポーネントでこのようなことをしてください

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

これsubstring(1)が必要なのは'/mypage?foo=bar'、このようなものがあれば、キー名は?foo

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.