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

Почему HttpParams не работает в нескольких строках в angular 4.3

Из Angular 4.3 они ввели HttpClient вместо Http. in HttpClient Я не могу использовать URLSearchParams для параметра запроса url. вместо URLSearchParams Я использую HttpParams

Эта работа

 var params = new HttpParams().append('a', '1').append('b', '2');

Но почему это не работает

var params = new HttpParams();
params.append('a', '1');
params.append('b', '2');
4b9b3361

Ответ 1

Новый HTTP-клиент работает с неизменяемым объектом запроса и всеми его составными частями, такими как HttpParams и HttpHeaders. Чтобы понять, почему см. Почему HTTP-запрос и все его составные части, такие как HttpHeaders и HttpParams, неизменны или читайте статью Инсайдеры ведут к перехватчикам и механике HttpClient в Angular.

Вот почему метод append объединяет параметры, а возвращает новый экземпляр объединенного объекта HttpParams при каждом вызове append:

  /**
   * Construct a new body with an appended value for the given parameter name.
   */
  append(param: string, value: string): HttpParams { 
        return this.clone({param, value, op: 'a'}); 
  }

  private clone(update: Update): HttpParams {
    const clone = new HttpParams({encoder: this.encoder}); <-------
    clone.cloneFrom = this.cloneFrom || this;
    clone.updates = (this.updates || []).concat([update]);
    return clone;                                          <--------
  }

Итак, здесь:

var params = new HttpParams().append('a', '1').append('b', '2');

append с параметром b обновляет объект, возвращаемый параметром append с параметром a.

Хотя при таком подходе

var params = new HttpParams();
params.append('a', '1');
params.append('b', '2');

append всегда обновляет начальное состояние HttpParams, и все операторы промежуточного append эффективно игнорируются.

Итак, вы должны использовать предыдущее возвращаемое значение:

var params = new HttpParams();
params = params.append('a', '1');
params = params.append('b', '2');

Или используйте ярлык с fromObject:

let searchParams = new HttpParams({
    fromObject: {
        query: query,
        sort: sort,
        order: order
    }
});

const modified = req.clone({params: searchParams});

Или используйте метод setParams по запросу напрямую:

const modified = req.clone({setParams: {'query': query, 'sort': sort, 'order': order}});

Кроме того, поскольку 5.1.x вы можете передать объект напрямую, а не экземпляр HttpParams:

const params = {
  'a': '1',
  'b': '2'
};

this.http.get('...', { params })

Ответ 2

Чтобы это работало

var params = new HttpParams();
params.append('a', '1');
params.append('b', '2');

Это нужно изменить на

var params = new HttpParams();
params = params.append('a', '1');
params = params.append('b', '2');

Он может быть циклическим и динамически добавлен

Ответ 4

Фактически @Maximus сделал довольно хорошее объяснение неизменности объекта HttpParams, и все, что вам нужно, - просто заменить params на свой клон внутри цикла.

Предполагая, что у вас есть нуль-ко-многим params, доступный, сохраняется в массиве, подобном структуре ниже:

"params": [
  {
    "key": "p1",
    "value": "v1"
  },
  {
    "key": "p2",
    "value": "v2"
  }
]

И согласно приведенной выше информации, следующая вспомогательная функция должна помочь:

export const getHttpParams = (params: Array<any>): HttpParams => {
  let res = new HttpParams();

  for (const item of params)
    res = res.append(item.key, item.value);

  return res;
};

Использование

const backend = 'http://httpstat.us/200';
const params = getHttpParams(backend.params);

return this.http.get(`${backend}`, { params });

Надеюсь, что это поможет!

Ответ 5

Я пробовал все остальные способы на этом посту, но имел небольшой успех. Поэтому я привязываю params к синглону HttpParams и вызываю toString() для возврата типа string. Затем я могу передать это http.get(), и все, кажется, отлично работает для создания параметров URL. Вот мой ng -v:

$ ng -v
    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
           |___/
@angular/cli: 1.4.2
node: 8.5.0
os: linux x64
@angular/animations: 4.4.3
@angular/cdk: 2.0.0-beta.10
@angular/common: 4.4.3
@angular/compiler: 4.4.3
@angular/core: 4.4.3
@angular/forms: 4.4.3
@angular/http: 4.4.3
@angular/material: 2.0.0-beta.10
@angular/platform-browser: 4.4.3
@angular/platform-browser-dynamic: 4.4.3
@angular/router: 4.4.3
@angular/cli: 1.4.2
@angular/compiler-cli: 4.4.3
@angular/language-service: 4.4.3
typescript: 2.3.4

Вот пример, который хорошо работает для меня:

// Simplified for example (I'm using Redux and won't go into all that)
private downloadState = { requestType: 'Auction', fileType: 'CSV' };

getStuffFromApi(): Observable<any> {
    const { requestType, fileType } = this.downloadState;
    const apiRoot = 'http://www.example.com';

    const params: string = new HttpParams()
        .set('RequestType', requestType)
        .set('FileType', fileType)
        .set('AuctionType', auctionType)
        .set('BackorderDay', backorderDay)
        .toString();

    return this.http.get(apiRoot, { params })
        .map(res => res.json())
        .catch(err => Observable.of(err.json()));

}