कोणीय 4.3 - HttpClient सेट परमेस


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

यह काम क्यों नहीं करता है? इसने केवल 'आआ' और न कि 'बब्ब' सेट किया

इसके अलावा, मेरे पास एक ऑब्जेक्ट {aaa: 111, bbb: 222} है, मैं बिना लूपिंग के सभी मान कैसे सेट कर सकता हूं?

अद्यतन (यह काम करने लगता है, लेकिन लूप से कैसे बचा जा सकता है?)

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

3
मैं आपसे सहमत हूं कि httpParams.set('bbb', '222');काम करना चाहिए। मैंने पहले कोशिश की और बहुत उलझन में था। लेकिन उस लाइन को httpParams = httpParams.set('bbb','222');काम से बदल दें । उन लोगों के लिए जो केवल 2 सेट कर रहे हैं, नीचे किसी अन्य उपयोगकर्ता का उत्तर देने वाला उत्तर भी अच्छा है।
एंजेला पी।

1
बस असाइनमेंट (=) का उपयोग करें क्योंकि @AngelaPan ने सुझाव दिया है और आपको लूप का उपयोग करने की आवश्यकता नहीं है। इसके अलावा उत्परिवर्तनीय और अपरिवर्तनीय के बारे में पढ़ें।
जुनैद

कृपया सशर्त HttpParams सेट अपडेट सुविधा के लिए वोट करें: github.com/angular/angular/issues/26021
सर्ज

जवाबों:


93

5.0.0-बीटा 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})
}

मैं 5.2.6 का उपयोग कर रहा हूं और यह निश्चित रूप से जब तक मैं स्पष्ट रूप से इसे लागू नहीं करता, तब तक यह परम टुकड़ा के लिए एक शब्दकोश नहीं लेगा any। क्या यह वास्तव में इच्छित उपयोग है?
गार्गॉयल

6
@ गर्गॉयल - { params: <any>params }ts संकलक मुद्दों से बचने के लिए आप किसी को भी अपनी वस्तु डाल सकते हैं
Kieran

2
अशक्त प्रकार के तार जो अशक्त हैं, "अशक्त" वापस आ जाएंगे और सपोर्ट नंबर, बूलियन और दिनांक नहीं है
उमर AMEZOUG

यहाँ संख्या, बूलियन और दिनांक समर्थन की कमी के लिए बग रिपोर्ट का लिंक दिया गया है: github.com/angular/angular/issues/23856
EpicVoyage

83

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

... हालांकि यह अजीब हो सकता है अगर आपको उनमें से किसी को भी शर्तों में लपेटने की आवश्यकता हो।

आपका लूप काम करता है क्योंकि आप लौटाए गए नए इंस्टेंस का संदर्भ ले रहे हैं। आपके द्वारा पोस्ट किया गया कोड काम नहीं करता है। यह बस सेट () कहता है, लेकिन परिणाम को नहीं पकड़ता है।

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

1
कैसे एक अयोग्य HttpParams की पसंद विचित्र है, यह अवरुद्ध बिंदु था और स्वीकृत उत्तर होना चाहिए
निकोलस

45

हाल के संस्करणों में @angular/common/http(5.0 और इसके बाद के संस्करण ), आप सीधे वस्तु को पास करने की fromObjectकुंजी का उपयोग कर सकते हैं HttpParamsOptions:

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

आप क्यों कह रहे हैं यह कोई भी वस्तु हो सकती है।
क्रिश्चियन मैथ्यू

@ChristianMatthew HttpParams के निर्माता "कोई वस्तु" नहीं ले सकते , यह HttpParamsOptions लेता है। यदि आपका मतलब है कि आप अनुरोध के रूप में किसी भी वस्तु को पारित कर सकते हैं: हाँ, लेकिन केवल v5 से। अन्यथा मुझे यकीन नहीं है कि आप क्या पूछ रहे हैं।
जोंशरशेप

TheObject से शब्द << ठीक से क्या है
ईसाई मैथ्यू

@ChristianMatthew मुझे नहीं पता कि आप क्या पूछ रहे हैं। क्या आप जानना चाहते हैं कि वह संपत्ति क्या है? क्या आपने एपीआई डॉक्स को देखा? या उत्तर में उदाहरण?
जॉन्सर्शपे

1
@ChristianMatthew मुझे नहीं पता कि आप क्या पूछ रहे हैं। आपका क्या मतलब है "एपीआई संस्करण"। कोणीय संस्करण? आप देख सकते हैं कि मैं उत्तर में किस प्रतिबद्धता से जुड़ा हुआ हूं और मैंने स्पष्ट रूप से यह 5.0 में पेश किया था। आप अभी जाकर इसे मास्टर में देख सकते हैं: github.com/angular/angular/blob/master/packages/common/http/src/… । यह मुझे स्पष्ट नहीं है कि आपको क्या समस्या है।
जोंशरशेप

21

मेरे लिए, setतरीकों का पीछा करना सबसे साफ तरीका है

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

3
HttpParams HttpHeaders की तरह अपरिवर्तनीय है, जिसका अर्थ है कि इस मामले में दूसरा .set () कॉल काम नहीं करेगा। इसे एक हिट में सेट करने की जरूरत है या ओप्पो () के साथ आउटपुट को एक नए वैरिएबल को असाइन करने की विधि के साथ जाता है, जैसा कि ओपी ने अपने अपडेट के लिए सुझाया था।
WPalombini

2
@WPalombini मैंने अभी माइक सेट करने की कोशिश की है। और यह काम करता है! मुझे लगता है कि यह केवल 2 मापदंडों वाले लोगों के लिए अच्छा है। यह समझना आसान है।
एंजेला पी।

19

आसान विकल्प के युगल

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

चूंकि HTTP Params वर्ग अपरिवर्तनीय है, इसलिए आपको सेट विधि की श्रृंखला बनाने की आवश्यकता है:

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

7

इसके इस्तेमाल से आप लूप से बच सकते हैं।

// 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 के बजाय सीधे पास किया जा सकता है।

यह दूसरा कारण है कि अगर आपने ऊपर वर्णित किसी भी सामान्य फ़ंक्शन जैसे कि HttpParams का उपयोग किया है, तो आप इसे आसानी से हटा सकते हैं या आवश्यकता के अनुसार परिवर्तन कर सकते हैं।


हाय इसके काम ठीक है, लेकिन अतिरिक्त अपरिभाषित प्रमुख मूल्य को परम के रूप में जोड़ते हैं
अभिजीत जगताप

3

जहाँ तक मैं इसे https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts पर कार्यान्वयन से देख सकता हूँ

आपको अलग से मान प्रदान करने होंगे - आप अपने पाश से बचने में सक्षम नहीं हैं।

एक कंस्ट्रक्टर भी है जो एक पैरामीटर के रूप में एक स्ट्रिंग लेता है, लेकिन यह फॉर्म में है param=value&param2=value2 इसलिए आपके लिए कोई सौदा नहीं है (दोनों मामलों में आप अपनी वस्तु को लूपिंग के साथ समाप्त करेंगे)।

आप हमेशा एक मुद्दे / सुविधा अनुरोध को कोणीय रिपोर्ट कर सकते हैं, जो मैं दृढ़ता से सलाह देता हूं: https://github.com/angular/angular/issues

पुनश्च: के बीच अंतर setऔर appendविधियों के बारे में याद रखें ;)


क्या अंतर हैं?
क्रिश्चियन मैथ्यू

2

चूंकि @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

2

किसी भी जटिल dto ऑब्जेक्ट (न केवल "स्ट्रिंग शब्दकोश") को परिवर्तित करने के लिए मेरा सहायक वर्ग (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

आपको वास्तव params.tsमें इसकी आवश्यकता नहीं है, कोणीय की अपनी एन्कोडिंग है। : कार्यान्वयन की जांच github.com/angular/angular/blob/master/packages/common/http/src/...
Davideas

1

यदि आप उदाहरण के लिए एक ही कुंजी नाम के साथ कई पैरामीटर जोड़ना चाहते हैं, तो बस जोड़ना चाहते थे: www.test.com/home?id=1&hl=2

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

एपेंड का उपयोग करें, यदि आप सेट का उपयोग करते हैं, तो यह एक ही कुंजी नाम के साथ पिछले मूल्य को अधिलेखित कर देगा।


0

यह समाधान मेरे लिए काम कर रहा है,

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.