Angular 4.3-HttpClient 설정 매개 변수


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

왜 이것이 작동하지 않습니까? 'aaa'만 설정하고 'bbb'는 설정하지 않습니다.

또한 개체가 있습니다 {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로만 설정하는 사람들에게는 아래 다른 사용자의 연쇄 답변도 좋습니다.
Angela P

1
@AngelaPan이 제안한대로 할당 (=)을 사용하고 루프를 사용할 필요가 없습니다. 변경 가능 및 불변에 대해서도 읽어보십시오.
Junaid

조건부 HttpParams 세트 업데이트 기능에 투표하십시오 : github.com/angular/angular/issues/26021
Serge

답변:


94

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

나는 5.2.6을 사용하고 있으며 명시 적으로 대소 문자를 구분하지 않는 한 params 조각에 대한 사전을 사용하지 않을 것 any입니다. 그것이 정말로 의도 된 용도입니까?
Gargoyle

6
@ Gargoyle- { params: <any>params }ts 컴파일러 문제를 피하기 위해 객체를 임의의 객체로 캐스팅 할 수 있습니다.
Kieran

2
널 (null)이 "널 (null)"를 지원하지 않는 번호, 부울 및 날짜 반환있는 문자열 형식의 PARAMS
오마르 AMEZOUG

다음은 Number, Boolean 및 Date 지원 부족에 대한 버그 보고서 링크입니다. github.com/angular/angular/issues/23856
EpicVoyage

83

HttpParams는 변경 불가능합니다. setappend방법은 기존 인스턴스를 수정하지 않습니다. 대신 변경 사항이 적용된 새 인스턴스를 반환합니다.

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

1
변경 불가능한 HttpParams의 선택이 얼마나 기괴한 지, 이것이 차단 지점이었고 받아 들여진 대답이어야합니다
Nicolas

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

왜 fromObject를 말하는거야? 모든 객체가 될 수 있습니다.
Christian Matthew

@ChristianMatthew의 생성자 HttpParams이 없다 "개체"를 가지고, 그것은 HttpParamsOptions합니다. 요청에 대한 매개 변수로 모든 객체를 전달할 수 있음을 의미하는 경우 : 예,하지만 v5에서만 가능합니다. 그렇지 않으면 당신이 무엇을 요구하는지 잘 모르겠습니다.
jonrsharpe

the word fromObject << 그게 뭐가 적절 하냐
Christian Matthew

@ChristianMatthew 당신이 무엇을 요구하는지 모르겠습니다. 그 속성이 무엇인지 알고 싶습니까? API 문서를 보셨습니까? 아니면 대답의 예?
jonrsharpe

1
@ChristianMatthew 당신이 무엇을 요구하는지 모르겠습니다. "API 버전"이란 무엇을 의미합니까? 각도 버전? 대답에서 내가 어떤 커밋에 연결했는지 볼 수 있으며 5.0에서 도입되었다고 명시 적으로 말했습니다. 지금 바로 마스터에서 볼 수도 있습니다 : github.com/angular/angular/blob/master/packages/common/http/src/… . 어떤 문제 가 있는지 나에게 명확하지 않습니다 .
jonrsharpe

21

저에게는 체인 set방식이 가장 깨끗한 방법입니다.

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

3
HttpParams는 HttpHeaders와 같이 변경 불가능합니다. 즉,이 경우 두 번째 .set () 호출이 작동하지 않습니다. 한 번의 히트로 설정하거나 OP가 업데이트에서 제안한대로 출력을 새 변수에 할당하는 .append () 메서드와 함께 이동해야합니다.
WPalombini

2
@WPalombini 방금 Mike의 체인 세트를 시도했습니다. 그리고 그것은 작동합니다! 매개 변수가 2 개 밖에없는 사람들에게 좋은 것 같아요. 이해하기 쉽습니다.
Angela P

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

이것은 받아 들여진 대답이어야합니다. 간단하고 깨끗합니다.
Karsus


9

HTTP Params 클래스는 불변이므로 set 메서드를 연결해야합니다.

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 대신 직접 전달할 수 있습니다.

이것은 위에서 언급 한 toHttpParams 와 같은 하나의 공통 함수를 사용한 경우 쉽게 제거하거나 필요한 경우 변경할 수 있는 또 다른 이유 입니다.


안녕의 작업 잘하지만 PARAM으로 APPEND 추가로 정의되지 않은 키 값
Abhijit Jagtap

3

https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts 의 구현에서 볼 수있는 한

값을 별도로 제공해야합니다. 루프를 피할 수 없습니다.

문자열을 매개 변수로 사용하는 생성자도 있지만 형식이 param=value&param2=value2있으므로 거래가 없습니다 (두 경우 모두 객체 루프를 완료합니다).

angular에 언제든지 문제 / 기능 요청을보고 할 수 있습니다. https://github.com/angular/angular/issues

추신 : setappend방법의 차이점에 대해 기억하십시오 ;)


차이점은 무엇입니까?
Christian Matthew

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 개체 ( "문자열 사전"뿐만 아니라)를 HttpParams로 변환하는 내 도우미 클래스 (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

정말 필요하지 않습니다. Angular params.ts에는 자체 인코딩이 있습니다. 구현 확인 : github.com/angular/angular/blob/master/packages/common/http/src/…
Davideas

1

예를 들어 동일한 키 이름으로 여러 매개 변수를 추가하려는 경우 추가하고 싶었습니다. www.test.com/home?id=1&id=2

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

추가를 사용하면 set을 사용하면 이전 값을 동일한 키 이름으로 덮어 씁니다.


0

이 솔루션은 저에게 효과적입니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.