Angular 4.3 - HttpClient set parametreleri


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

Bu neden çalışmıyor? Sadece 'aaa'yı ayarladı,' bbb'yi DEĞİL

Ayrıca, bir nesnem var {aaa: 111, bbb: 222} Döngü olmadan tüm değerleri nasıl ayarlayabilirim?

GÜNCELLEME (bu işe yarıyor gibi görünüyor, ancak döngüden nasıl kaçınabilir?)

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

3
httpParams.set('bbb', '222');İşe yaraması gerektiğine katılıyorum . İlk önce denedim ve kafam çok karıştı. Ama bu satırı httpParams = httpParams.set('bbb','222');eserlerle değiştirin . sadece 2'yi ayarlayanlar için, aşağıdaki başka bir Kullanıcının zincirleme cevabı da güzel.
Angela P

1
@AngelaPan'ın önerdiği gibi atama (=) kullanın ve döngü kullanmak zorunda değilsiniz. Ayrıca değiştirilebilir ve değişmez hakkında bilgi edinin.
Junaid

lütfen koşullu HttpParams set güncelleme özelliği için oy verin: github.com/angular/angular/issues/26021
Serge

Yanıtlar:


94

5.0.0-beta.6'dan önce

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

5.0.0-beta.6'dan beri

5.0.0-beta.6'dan (2017-09-03) bu yana yeni özellik eklediler (HttpClient üstbilgileri ve parametreleri için nesne haritasını kabul edin)

İleriye doğru nesne HttpParams yerine doğrudan iletilebilir.

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

5.2.6 kullanıyorum ve açıkça belirtmedikçe params parçası için kesinlikle bir sözlük almayacak any. Gerçekten amaçlanan kullanım bu mu?
Gargoyle

6
@Gargoyle - { params: <any>params }ts derleyici sorunlarını önlemek için nesnenizi herhangi birine çevirebilirsiniz
Kieran

2
Null olan string
türündeki parametreler

Sayı, Boole ve Tarih desteğinin eksikliğine ilişkin hata raporuna bir bağlantı: github.com/angular/angular/issues/23856
EpicVoyage

83

HttpParams'ın değişmez olması amaçlanmıştır. setVe appendyöntemler mevcut örneğini değiştirmez. Bunun yerine, değişiklikler uygulanarak yeni örnekler döndürürler.

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

Bu yaklaşım, yöntem zincirleme ile iyi çalışır:

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

... bunlardan herhangi birini koşullara uydurmanız gerekirse, bu garip olabilir.

Döngünüz, döndürülen yeni örneğe bir referans aldığınız için çalışır. Gönderdiğiniz kod çalışmıyor, çalışmıyor. Sadece set () 'i çağırır ama sonucu almaz.

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

1
Değişmez bir HttpParams seçimi ne kadar tuhaf, engelleme noktası buydu ve kabul edilen cevap olmalı
Nicolas

45

Daha yeni sürümlerinde @angular/common/http(5.0 ve üstü, görünüşe göre), nesneyi doğrudan içeri iletmek için fromObjectanahtarını kullanabilirsiniz HttpParamsOptions:

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

Bu sadece kaputun altında bir forEachdöngü oluşturur :

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

neden fromObject diyorsun? Herhangi bir nesne olabilir.
Hıristiyan Matthew

@ChristianMatthew yapıcısı HttpParams olamaz "herhangi bir nesne" almak, bu HttpParamsOptions sürer. Herhangi bir nesneyi bir isteğe parametre olarak iletebileceğinizi kastediyorsanız: evet, ancak yalnızca v5'ten. Aksi takdirde ne istediğinden emin değilim.
jonrsharpe

Nesne << kelimesi bu doğru nedir
Hıristiyan Matta

@ChristianMatthew Ne sorduğunu bilmiyorum. Bu mülkün ne olduğunu bilmek ister misin? API belgelerine baktınız mı? Veya cevaptaki örnek?
jonrsharpe

1
@ChristianMatthew Ne sorduğunu bilmiyorum. "API sürümü" ne demek? Açısal versiyon? Yanıtta hangi işleme bağladığımı görebilirsiniz ve 5.0'da tanıtıldığını açıkça söyledim. Ayrıca şu anda ana olarak gidip görebilirsiniz: github.com/angular/angular/blob/master/packages/common/http/src/… . Hangi sorunun olduğu bana açık değil .
jonrsharpe

21

Bana gelince, zincirleme setyöntemleri en temiz yol

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

3
HttpParams, HttpHeaders gibi değişmezdir, bu da ikinci .set () çağrısının bu durumda çalışmayacağı anlamına gelir. Bir vuruşta ayarlanması gerekir veya OP'nin güncellemesinde önerdiği gibi çıktıyı yeni bir değişkene atayan .append () yöntemiyle birlikte gider.
WPalombini

2
@WPalombini Mike'ın zincirleme setini denedim. ve işe yarıyor! Bence sadece 2 parametresi olan insanlar için güzel. Anlaması kolay.
Angela P

19

Birkaç Kolay Alternatif

HttpParamsNesneleri kullanmadan

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

this.http.post(url, body);

HttpParamsNesneleri Kullanma

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

this.http.post(url, body);

Kabul edilen cevap bu olmalıdır. Basit ve temiz.
Karsus

14

Bunu yapmanın başka bir yolu:

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


bu sihirbazlığı denemek zorunda kalacak
Christian Matthew

9

HTTP Params sınıfı değişmez olduğundan, set yöntemini zincirlemeniz gerekir:

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

7

Bunu kullanarak döngüden kaçınabilirsiniz.

// 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());

Ayrıca, yaygın olarak kullandığınız hizmette toHttpParams işlevini yapmanızı öneririm . Böylece, nesneyi HttpParams'a dönüştürmek için işlevi çağırabilirsiniz .

/**
 * 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());
}

Güncelleme:

5.0.0-beta.6'dan (2017-09-03) bu yana yeni özellik eklediler ( HttpClient üstbilgileri ve parametreleri için nesne haritasını kabul edin )

İleriye doğru nesne HttpParams yerine doğrudan iletilebilir.

Bu, yukarıda bahsedilen toHttpParams gibi ortak bir işlevi kullandıysanız , bunu kolayca kaldırabilir veya gerekirse değişiklik yapabilirsiniz.


Merhaba, sorunsuz çalışıyor ancak fazladan tanımlanmamış anahtar değerini param olarak ekleyin
Abhijit Jagtap

3

Https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts adresindeki uygulamadan görebildiğim kadarıyla

Değerleri ayrı ayrı sağlamalısınız - Döngünüzden kaçınamazsınız.

Ayrıca bir dizgeyi parametre olarak alan bir kurucu da vardır, ancak formdadır, param=value&param2=value2bu nedenle Sizin için bir anlaşma yoktur (her iki durumda da nesnenizi döngüye almayı bitireceksiniz).

Her zaman bir sorunu / özellik talebini angular'a bildirebilirsiniz, bunu şiddetle tavsiye ederim: https://github.com/angular/angular/issues

Not: setve appendyöntemler arasındaki farkı hatırlayın ;)


Farklılıklar nedir?
Christian Matthew

2

@MaciejTreder döngü yapmamız gerektiğini onayladığından, burada isteğe bağlı olarak bir dizi varsayılan parametreye eklemenize izin verecek bir sarmalayıcı var:

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

Bunu şu şekilde kullanabilirsiniz:

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

2

Herhangi bir karmaşık dto nesnesini (yalnızca "dize sözlüğü" değil) HttpParams'a dönüştürmek için yardımcı sınıfım (ts):

import { HttpParams } from "@angular/common/http";

export class HttpHelper {
  static toHttpParams(obj: any): HttpParams {
    return this.addToHttpParams(new HttpParams(), obj, null);
  }

  private static addToHttpParams(params: HttpParams, obj: any, prefix: string): HttpParams {    
    for (const p in obj) {
      if (obj.hasOwnProperty(p)) {
        var k = p;
        if (prefix) {
          if (p.match(/^-{0,1}\d+$/)) {
            k = prefix + "[" + p + "]";
          } else {
            k = prefix + "." + p;
          }
        }        
        var v = obj[p];
        if (v !== null && typeof v === "object" && !(v instanceof Date)) {
          params = this.addToHttpParams(params, v, k);
        } else if (v !== undefined) {
          if (v instanceof Date) {
            params = params.set(k, (v as Date).toISOString()); //serialize date as you want
          }
          else {
            params = params.set(k, v);
          }

        }
      }
    }
    return params;
  }
}

console.info(
  HttpHelper.toHttpParams({
    id: 10,
    date: new Date(),
    states: [1, 3],
    child: {
      code: "111"
    }
  }).toString()
); // id=10&date=2019-08-02T13:19:09.014Z&states%5B0%5D=1&states%5B1%5D=3&child.code=111

Buna gerçekten ihtiyacınız yok, Angular'ın params.tskendi kodlaması var. Uygulamayı kontrol edin: github.com/angular/angular/blob/master/packages/common/http/src/…
Davideas

1

Aynı anahtar adına sahip birkaç parametre eklemek istiyorsanız, örneğin: www.test.com/home?id=1&id=2

let params = new HttpParams();
params = params.append(key, value);

Eklemeyi kullanın, eğer set kullanırsanız, aynı anahtar adıyla önceki değerin üzerine yazacaktır.


0

Bu çözümler benim için çalışıyor,

let params = new HttpParams(); Object.keys(data).forEach(p => { params = params.append(p.toString(), data[p].toString()); });

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.