Подтвердить что ты не робот

Angular 4.3 - Параметры набора HttpClient

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

Почему это не работает? Он устанавливает только "aaa" и NOT "bbb"

Кроме того, у меня есть объект {aaa: 111, bbb: 222} Как установить все значения без цикла?

UPDATE (похоже, это работает, но как избежать цикла?)

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

Ответ 1

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

Ответ 2

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

Ответ 3

В более поздних версиях @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]);
});

Ответ 4

Что касается меня, то цепочки set - самый чистый способ

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

Ответ 5

Пара простых альтернатив

Без использования объектов 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);

Ответ 6

Другой вариант сделать это:

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

Ответ 7

Так как класс HTTP Params является неизменным, вам нужно связать метод set:

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

Ответ 8

Используя это, вы можете избежать цикла.

// 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-бета .6 (2017-09-03) они добавили новую функцию (принять карту объектов для заголовков и параметров HttpClient)

В дальнейшем объект может быть передан напрямую вместо HttpParams.

Это еще одна причина, если вы использовали одну общую функцию, такую как toHttpParams, упомянутую выше, вы можете легко удалить ее или внести изменения, если это необходимо.

Ответ 9

Насколько я вижу из реализации в https://github.com/angular/angular/blob/master/packages/common/http/src/params.ts

Вы должны указывать значения отдельно - вы не можете избежать цикла.

Существует также конструктор, который принимает строку как параметр, но находится в форме param=value&param2=value2, поэтому для вас нет сделки (в обоих случаях вы закончите с циклом вашего объекта).

Вы всегда можете сообщить о проблеме/функции запрос angular, что я настоятельно рекомендую: https://github.com/angular/angular/issues

PS: Помните о различии между методами set и append;)

Ответ 10

Так как @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

Ответ 11

Это решение работает на меня,

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