【问题标题】:How to return HttpClient response body from a request?如何从请求中返回 HttpClient 响应正文?
【发布时间】:2019-03-31 14:53:52
【问题描述】:

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

如何让我的pull_categories() 函数等到收到响应正文然后返回?而不是返回一个空对象,因为它不会等待甚至在我下面的例子中调用它。


service.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;
        }
    );
}

组件.ts

categories = [];

constructor(private route: ActivatedRoute) { }

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

解析器.ts

constructor(private categoriesService: CategoriesService) { }

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

app-routing.module.ts

{
    path: '',
    component: HomeComponent,
    resolve: {categories: CategoriesResolverService}
}

【问题讨论】:

  • 您可以使用 Angular 路由保护等到数据加载完毕后再转到该页面。
  • @PavanBahuguni 这就是我正在尝试做的,但到目前为止还没有工作

标签: angular typescript angular-httpclient angular-resolver


【解决方案1】:

您正在从您的服务(以及您的解析器)返回一个 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。

【讨论】:

  • 感谢您的详细帮助,我一定会记下这些。
【解决方案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 部分返回响应。

【讨论】:

    【解决方案3】:

    从后端获取数据的另一种方法是,而不是订阅数据,您也可以返回一个 promise,然后在组件中使用异步等待

    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) {
    
      }
    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      相关资源
      最近更新 更多