Почему 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');
Ответы
Ответ 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');
Он может быть циклическим и динамически добавлен
Ответ 3
Так как 5.0.0-beta.6 (2017-09-03) новая функция ( принять карту объекта для HttpClient заголовки и параметры).
Теперь мы можем передать объект напрямую, а не HttpParams
:
const params = {
'a': '1',
'b': '2'
};
this.http.get('...', { params })
или вместо HttpHeaders
:
http.get('/url', {
headers: {'My-Header': 'header value'}
})
Ответ 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()));
}