【问题标题】:How do you declare a GET call with parameters?如何声明带参数的 GET 调用?
【发布时间】:2021-08-03 07:33:56
【问题描述】:
从 API 获取数据的一种技术是在服务中这样声明它:
getItems$ = this.httpClient.get<Item[]>(this.url);
然后订阅它或在消费组件中使用异步。
如果get调用需要get by id之类的参数,你会怎么做?
编辑:以上是使用 RxJS 流的声明性方法的示例。 getItems$ 是一个属性。
所以问题是,当使用带有 property 定义流而不是调用 getItems(itemId) 方法的声明性方法时,如何传入参数?
【问题讨论】:
标签:
angular
rxjs
angular-httpclient
rxjs-observables
【解决方案1】:
要处理任何“参数”,您可以使用 Subject 或 BehaviorSubject 创建另一个操作流。然后将“参数”发送到流中。
这是我的一个应用程序的示例。
// Handle product selection action
private productSelectedSubject = new BehaviorSubject<number>(0);
productSelectedAction$ = this.productSelectedSubject.asObservable();
product$ = this.productSelectedAction$
.pipe(
filter(id => !!id),
switchMap(selectedProductId =>
this.http.get<Product>(`${this.productsUrl}/${selectedProductId}`)
));
// Selected product was changed
changeSelectedProduct(selectedProductId: number): void {
this.productSelectedSubject.next(selectedProductId);
}
这里我们创建一个初始值为 0 的 BehaviorSubject。(您可以使用没有初始值的 Subject。)
当用户选择一个产品(或确定具体产品)时,该产品的 id 被发送到productSelectedSubject
然后,每次有新产品 ID 发送到流中时,此代码都会使用管道做出反应。管道中的第一个运算符过滤掉任何无效的 Id。然后 switchMap 使用发出的产品 ID 来发出 http get。
我有一个完整的例子,它还在这里设置了额外的分页“参数”:https://github.com/DeborahK/Angular-ActionStreams
【解决方案2】:
我喜欢你的问题。我也总是尝试以声明的方式定义我的 observables。然而,当涉及带参数的方法时(尤其是在 Angular 服务中),我倾向于只使用返回 observables 的仅使用函数:
class ItemService {
public getItem(id: string) {
return this.http.get<Item>(`${this.apiRoot}/items/${id}`);
}
}
如果服务本身负责管理这些“参数”的状态,那么使用 @DeborahK 提到的主题为消费者提供传递值的工具是有意义的。
但是,如果组件负责这些参数,那么通常不需要有 Subjects,因为这些参数值通常来自其他可观察的来源,例如反应式表单控件或路由参数。
例如:
class ItemComponent {
private id$ = this.route.paramMap.pipe(params => params.get('id'));
public item$ = this.id$.pipe(
switchMap(id => this.itemService.getItem(id))
);
constructor(
private route: ActivatedRoute,
private itemService: ItemService
) { }
}
在组件中注意,item$ 仍然以您喜欢的声明方式定义。另请注意,我做了@DeborahK 提到的事情并从另一个流中定义它(另一个流恰好是不同的可观察对象,而不是主题)。
【解决方案3】:
这取决于您请求的 http api。
由于 get 请求没有正文,因此通常将参数添加到 url,如下所示:
http://example.com/customer?id=25
HttpClient的get、post、put等方法有第二个options参数,可以有HttpParams类型的params属性,可以在其中设置参数
data$ = this.http.get<item[]>(this.url,{params: new HttpParams().set('id',25)}) `
这将处理添加到实际请求的 url。