处理两个 HTTP 请求(Angular + RxJS)
Handling two HTTP requests (Angular + RxJS)
这是我的第一个 angular 项目,我对 Observables 和 RxJS 还不是很熟悉。
在我的项目中,起初我想用 get 请求获取所有通知。之后,我想获取最后一个通知的 ID,这样我就可以向服务器发送 post 请求以将它们全部标记为已读。
所以服务中的代码如下所示:
getNotifications(limit: number, page: number): any {
return this.http
.get<INotifications>(
`${API_URL}/notifications?direction=desc&limit=${limit}&order_by=created_at&page=${page}`
)
.pipe(
switchMap((response) => {
const id = response.data[0].id;
return this.markNotificationsAsRead(id);
})
);
}
markNotificationsAsRead(id: number) {
return this.http.post(`${API_URL}/notifications/${id}/mark_all_as_read`, {
id,
});
}
我尝试使用 switchMap 和 mergeMap
运算符,但我得到
RangeError: Invalid array length
组件中的代码:
fetchData() {
this.notificationsService.getNotifications(this.limit, this.meta?.next_page || 1).subscribe(
(response) => {
this.notifications = [...this.notifications, ...response.data];
this.meta = response.meta;
this.isLoading = false;
// const mostRecentNotification = response.data[0].id;
// this.markNotificationsAsRead(mostRecentNotification);
},
(error) => {
this.handleErrors(error);
}
);
}
顺便说一句:我可以让它工作,方法是删除 fetchData 函数中的这个注释部分,并且只返回 get 请求而不用管道传递给另一个操作员,但我想尝试一下并在服务中进行。
知道为什么它不起作用吗?
所以如果我没理解错的话,你正在尝试获取一些数据(通知),当数据返回时发出 post 请求,然后在你的组件中显示数据。
您遇到的问题是,您没有设法从服务发出 post 请求并将数据获取到组件。
问题
我看到的问题在这里:
switchMap((response) => {
const id = response.data[0].id;
return this.markNotificationsAsRead(id);
})
这是在做什么,return markNotificationsAsRead()
对您 subscribe
的价值,而不是您期望的通知数据。
解决方案
您使用 switchMap()
将两个请求合二为一是正确的。我相信你只需要一个小的修改:
switchMap((response) => {
const id = response.data[0].id;
return this.markNotificationsAsRead(id).pipe(map(() => response));
})
通过添加 pipe(map(() => response))
,您可以 return 获取第一个可观察值的值,同时仍然订阅第二个(并因此发出 post 请求)。
这是我的第一个 angular 项目,我对 Observables 和 RxJS 还不是很熟悉。 在我的项目中,起初我想用 get 请求获取所有通知。之后,我想获取最后一个通知的 ID,这样我就可以向服务器发送 post 请求以将它们全部标记为已读。 所以服务中的代码如下所示:
getNotifications(limit: number, page: number): any {
return this.http
.get<INotifications>(
`${API_URL}/notifications?direction=desc&limit=${limit}&order_by=created_at&page=${page}`
)
.pipe(
switchMap((response) => {
const id = response.data[0].id;
return this.markNotificationsAsRead(id);
})
);
}
markNotificationsAsRead(id: number) {
return this.http.post(`${API_URL}/notifications/${id}/mark_all_as_read`, {
id,
});
}
我尝试使用 switchMap 和 mergeMap
运算符,但我得到
RangeError: Invalid array length
组件中的代码:
fetchData() {
this.notificationsService.getNotifications(this.limit, this.meta?.next_page || 1).subscribe(
(response) => {
this.notifications = [...this.notifications, ...response.data];
this.meta = response.meta;
this.isLoading = false;
// const mostRecentNotification = response.data[0].id;
// this.markNotificationsAsRead(mostRecentNotification);
},
(error) => {
this.handleErrors(error);
}
);
}
顺便说一句:我可以让它工作,方法是删除 fetchData 函数中的这个注释部分,并且只返回 get 请求而不用管道传递给另一个操作员,但我想尝试一下并在服务中进行。 知道为什么它不起作用吗?
所以如果我没理解错的话,你正在尝试获取一些数据(通知),当数据返回时发出 post 请求,然后在你的组件中显示数据。
您遇到的问题是,您没有设法从服务发出 post 请求并将数据获取到组件。
问题
我看到的问题在这里:
switchMap((response) => {
const id = response.data[0].id;
return this.markNotificationsAsRead(id);
})
这是在做什么,return markNotificationsAsRead()
对您 subscribe
的价值,而不是您期望的通知数据。
解决方案
您使用 switchMap()
将两个请求合二为一是正确的。我相信你只需要一个小的修改:
switchMap((response) => {
const id = response.data[0].id;
return this.markNotificationsAsRead(id).pipe(map(() => response));
})
通过添加 pipe(map(() => response))
,您可以 return 获取第一个可观察值的值,同时仍然订阅第二个(并因此发出 post 请求)。