如何从请求返回HttpClient响应主体?

时间:2019-03-31 14:53:53

标签: angular typescript angular-httpclient angular-resolver

我有一个依赖于API响应的内容的组件。我已经设置了解析器,但是在数据准备好之前它仍然会返回。

如何让我的par(mfrow=c(1,2))函数等待直到收到响应正文然后返回?而不是返回一个空对象,因为它不会等待,甚至在下面的情况下也不会调用它。


service.ts

pull_categories()

component.ts

private _categories = [];

constructor(private http: HttpClient) { }

pull_categories() {
    this.http.post('https://myapi.com/something', null)
    .subscribe(
        data => {
            this._categories = data['response'];
            return this._categories;
        }
    );
}

resolver.ts

categories = [];

constructor(private route: ActivatedRoute) { }

ngOnInit() {
    this.route.data.subscribe(
        (data: Data) => {
            this.categories = data.categories;
        }
    );
}

app-routing.module.ts

constructor(private categoriesService: CategoriesService) { }

resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any {
    return this.categoriesService.pull_categories();
}

3 个答案:

答案 0 :(得分:2)

您要从服务(进而是解析程序)返回Subscription,而不是返回Observable。不要订阅服务。并指定返回值,以避免自己陷入困境:

getCategories(): Observable<Array<Category>> {
  return this.http.get<Something>('https://myapi.com/something').pipe(
    map(something => something.response)
  );
}

注意

  • 尊重命名约定
  • 使用GET来获取数据而不是POST
  • 该方法定义了它实际返回的内容
  • HttpClient.get()方法的泛型重载的使用,该方法允许指定响应主体的预期类型
  • 在服务中具有实例字段是错误的(也是不必要的)。

阅读HttpClient指南和RxJS quide。

答案 1 :(得分:2)

第一件事,在service.ts中,您不需要订阅,您应该在要实际使用数据的位置进行订阅。 subscribe方法返回Subscription,而不返回http api的响应。

您可以将服务方法更新为

pull_categories(): Observable<any> {
    return this.http.post('https://myapi.com/something', null);
}

pull_categories方法将立即返回Observable,当您在组件中(或任何地方)对其进行订阅时,将执行http调用,并且将在您的subscribe中返回响应部分。

答案 2 :(得分:1)

从后端获取数据的另一种方法是订阅数据,而不是订阅数据,还可以返回一个promise,然后在组件中使用async await

pull_categories(): any {
    return this.http.post('https://myapi.com/something', null).toPromise();
} 

这会将承诺返回给您的组件,您还可以按以下方式使用它:

async getCategories() {
  try {
    const categories = await this.service.pull_categories();
  } catch (e) {

  }
}