冒泡 HTTP post 对组件的响应

Bubble up HTTP post response to component

如何让 UserCourseServicesetUserCourses 的结果冒泡到 DashboardBodyHomeCourseModalComponent?目前,result returns null.

此外,我目前正在传递一个名为 courseSelectedOptions 的数组,它对我的​​ API 执行多个 HTTP 调用。在最后一个 API 调用结束时,我想冒泡一个 HTTP post 响应到我的组件。

UserCourseService

setUserCourses(userId: string, courseSelectedOptions: number[]): Promise<unknown | void> {
return this.firebaseService.generateToken().then((token: string) => {
  this.logger.debug(`Token generated for setUserCourses: ${token}`);
  return observableFrom(courseSelectedOptions)
    .pipe(
      concatMap((courseSelectedOption) =>
        this.httpClient.post(
          `${environment.apiBasePath}/userCourses`,
          {
            user_id: userId,
            course_id: courseSelectedOption,
          },
          { headers: { authorization: `Bearer ${token}` } }
        )
      )
    )
    .subscribe(
      (response) => this.logger.debug(`setUserCourses response: ${JSON.stringify(response)}`),
      (error) => this.logger.debug(`setUserCourses error: ${JSON.stringify(error)}`),
      () => this.logger.debug('setUserCourses complete')
    );
});
}

DashboardBodyHomeFacade

setUserCourses(userId: string, courseSelectedOptions: number[]): Promise<unknown | void> {
    return this.userCourseService.setUserCourses(userId, courseSelectedOptions);
}

DashboardBodyHomeCourseModalComponent

this.dashboardBodyHomeFacade
.setUserCourses(this.user.id, this.courseSelectedOptions)
.then((result: unknown) => {
  if (result) {
    this.toastrService.success('Your courses have been selected.', 'Great!');
    this.bsModalRef.hide();
  } else {
    this.toastrService.warning('Something has gone wrong. Please try again.', 'Oops!');
  }
})
.catch(() => {
  this.toastrService.warning('Something has gone wrong. Please try again.', 'Oops!');
});

这是混合 observables 和 promises 的经典案例。我建议您使用 RxJS from 函数将承诺转换为可观察对象。之后,您可以使用高阶映射运算符(此处为 switchMap)映射到 HTTP 请求,从服务中 return 并在组件中订阅。

服务

setUserCourses(userId: string, courseSelectedOptions: number[]): Observable<any> { // <-- return the observable
  return from(this.firebaseService.generateToken()).pipe(
    switchMap(token => {
      this.logger.debug(`Token generated for setUserCourses: ${token}`);
      return this.httpClient.post(
        `${environment.apiBasePath}/userCourses`,
        {
          user_id: userId,
          course_id: courseSelectedOptions,
        },
        { headers: { authorization: `Bearer ${token}` } }
      )
    }),
    tap(
      (response) => this.logger.debug(`setUserCourses response: ${JSON.stringify(response)}`),
      (error) => this.logger.debug(`setUserCourses error: ${JSON.stringify(error)}`),
      () => this.logger.debug('setUserCourses complete')
    )
  );
}

组件

this.dashboardBodyHomeFacade.setUserCourses(this.user.id, this.courseSelectedOptions).subscribe(
  result => {
    if (result) {
      this.toastrService.success('Your courses have been selected.', 'Great!');
      this.bsModalRef.hide();
    } else {
      this.toastrService.warning('Something has gone wrong. Please try again.', 'Oops!');
    }
  },
  error => this.toastrService.warning('Something has gone wrong. Please try again.', 'Oops!')
);

更新:对 courseSelectedOptions

中每个项目的多个请求

您可以使用 RxJS forkJoin 函数和 Array#mapcourseSelectedOptions 中的每个项目触发多个并行 HTTP 请求。尝试以下

setUserCourses(userId: string, courseSelectedOptions: number[]): Observable<any> { // <-- return the observable
  return from(this.firebaseService.generateToken()).pipe(
    switchMap(token => {
      this.logger.debug(`Token generated for setUserCourses: ${token}`);
      return forkJoin(courseSelectedOptions.map(courseSelectedOption => // <-- trigger parallel requests for each item in `courseSelectedOptions`
        this.httpClient.post(
          `${environment.apiBasePath}/userCourses`,
          {
            user_id: userId,
            course_id: courseSelectedOption,
          },
          { headers: { authorization: `Bearer ${token}` } }
        )
      ))
    }),
    tap(
      (response) => this.logger.debug(`setUserCourses response: ${JSON.stringify(response)}`),
      (error) => this.logger.debug(`setUserCourses error: ${JSON.stringify(error)}`),
      () => this.logger.debug('setUserCourses complete')
    )
  );
}