web-dev-qa-db-ja.com

Angular 4.3 - HttpClientがパラメータを設定

let httpParams = new HttpParams().set('aaa', '111');
httpParams.set('bbb', '222');

なぜこれがうまくいかないのですか? 'aaa'だけを設定し、 'bbb'は設定しない

また、オブジェクト{aaa:111、bbb:222}があります。ループせずにすべての値を設定するにはどうすればよいですか。

UPDATE(これはうまくいくようですが、どうすればループを回避できますか?)

let httpParams = new HttpParams();
Object.keys(data).forEach(function (key) {
     httpParams = httpParams.append(key, data[key]);
});
58
Michalis

5.0.0-beta.6より前

let httpParams = new HttpParams();
Object.keys(data).forEach(function (key) {
     httpParams = httpParams.append(key, data[key]);
});

5.0.0-beta.6以降

5.0.0-beta.6以降(2017-09-03)彼らは新しい機能を追加しました(HttpClientヘッダとパラメータのオブジェクトマップを受け入れます)

HttpParamsの代わりにオブジェクトを直接渡すことができます。

getCountries(data: any) {
    // We don't need any more these lines
    // let httpParams = new HttpParams();
    // Object.keys(data).forEach(function (key) {
    //     httpParams = httpParams.append(key, data[key]);
    // });

    return this.httpClient.get("/api/countries", {params: data})
}
64
Michalis

HttpParamsは不変であることを意図しています。 setおよびappendメソッドは既存のインスタンスを変更しません。代わりに、変更を適用して新しいインスタンスを返します。

let params = new HttpParams().set('aaa', 'A');    // now it has aaa
params = params.set('bbb', 'B');                  // now it has both

このアプローチは、メソッドチェーンとうまく連携します。

const params = new HttpParams()
  .set('one', '1')
  .set('two', '2');

あなたが条件でそれらのうちのどれかをラップする必要があるならば...しかしそれは厄介かもしれません。

返された新しいインスタンスへの参照を取得しているので、ループは機能します。あなたが投稿したコードはうまくいきません。 set()を呼び出すだけですが、結果は取得されません。

let httpParams = new HttpParams().set('aaa', '111'); // now it has aaa
httpParams.set('bbb', '222');                        // result has both but is discarded
60
Rich

最近のバージョンの@angular/common/http(その外観では5.0以上)では、 fromObjectHttpParamsOptionsキーを使用してオブジェクトを直接渡すことができます。

let httpParams = new HttpParams({ fromObject: { aaa: 111, bbb: 222 } });

ただし、これはフードの下でforEachループ を実行するだけです

this.map = new Map<string, string[]>();
Object.keys(options.fromObject).forEach(key => {
  const value = (options.fromObject as any)[key];
  this.map !.set(key, Array.isArray(value) ? value : [value]);
});
32
jonrsharpe

私にとってはsetメソッドをチェーニングするのが最もきれいな方法です

const params = new HttpParams()
.set('aaa', '111')
.set('bbb', "222");
18
Mike Kovetsky

簡単な選択肢のカップル

HttpParamsオブジェクトを使わずに

let body = {
   params : {
    'email' : emailId,
    'password' : password
   }
}

this.http.post(url, body);

HttpParamsオブジェクトを使う

let body = new HttpParams({
  fromObject : {
    'email' : emailId,
    'password' : password
  }
})

this.http.post(url, body);
9
Debojyoti

それを行うためのもう1つの選択肢があります。

this.httpClient.get('path', {
    params: Object.entries(data).reduce(
    (params, [key, value]) => params.set(key, value), new HttpParams());
});
8

HTTP Paramsクラスは不変なので、setメソッドをチェインする必要があります。

const params = new HttpParams()
.set('aaa', '111')
.set('bbb', "222");
6

これを使用すると、ループを回避できます。

// obj is the params object with key-value pair. 
// This is how you convert that to HttpParams and pass this to GET API. 

const params = Object.getOwnPropertyNames(obj)
               .reduce((p, key) => p.set(key, obj[key]), new HttpParams());

さらに、私はあなたのよく使われるサービスでtoHttpParams関数を作ることを提案します。そのため、関数を呼び出してオブジェクトをHttpParamsに変換できます。

/**
 * Convert Object to HttpParams
 * @param {Object} obj
 * @returns {HttpParams}
 */
toHttpParams(obj: Object): HttpParams {
    return Object.getOwnPropertyNames(obj)
        .reduce((p, key) => p.set(key, obj[key]), new HttpParams());
}

更新:

5.0.0-beta.6以降(2017-09-03)彼らは新しい機能を追加しました( HttpClientヘッダとパラメータ用のオブジェクトマップを受け入れます

HttpParamsの代わりにオブジェクトを直接渡すことができます。

上記のtoHttpParamsのような共通の関数を使用した場合は、これがもう1つの理由です。必要に応じてそれを簡単に削除するか、変更を加えることができます。

5
Lahar Shah

実装から見ることができる限り https://github.com/angular/angular/blob/master/packages/common/http:// src/params.ts

あなたは別に値を提供しなければなりません - あなたはあなたのループを避けることができません。

パラメータとして文字列を取るコンストラクタもありますが、それはparam=value&param2=value2の形式になっているので、あなたには関係ありません(どちらの場合も、オブジェクトのループを終了します)。

あなたはいつでもissue/feature requestをAngularに報告することができます、私が強くお勧めします: https://github.com/angular/angular/issues

PS:setメソッドとappendメソッドの違いについて覚えておいてください。

2
Maciej Treder

@MaciejTrederはループする必要があることを確認しているので、ここでオプションのデフォルトパラメータのセットに追加できるラッパーを次に示します。

function genParams(params: object, httpParams = new HttpParams()): object {
    Object.keys(params)
        .filter(key => {
            let v = params[key];
            return (Array.isArray(v) || typeof v === 'string') ? 
                (v.length > 0) : 
                (v !== null && v !== undefined);
        })
        .forEach(key => {
            httpParams = httpParams.set(key, params[key]);
        });
    return { params: httpParams };
}

あなたはそのようにそれを使うことができます:

const OPTIONS = {
    headers: new HttpHeaders({
        'Content-Type': 'application/json'
    }),
    params: new HttpParams().set('verbose', 'true')
};
let opts = Object.assign({}, OPTIONS, genParams({ id: 1 }, OPTIONS.params));
this.http.get(BASE_URL, opts); // --> ...?verbose=true&id=1
1
James Irwin