How to return HttpClient response body from a request?

两盒软妹~` 提交于 2021-01-28 05:06:48

问题


I have a component that relies on an API response for its content. I have set up the resolver but it still returns before my data is ready.

How can I make my pull_categories() function wait until the response body is received and then return? Rather than returning an empty object because it won't wait or even call it in my case below.


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

component.ts

categories = [];

constructor(private route: ActivatedRoute) { }

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

resolver.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}
}

回答1:


First thing, in service.ts you don't need to subscribe, You should subscribe where you want to actually consume the data. subscribe method returns Subscription, not the response from the http api.

You can update your service method as

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

pull_categories method will return immediately with an Observable, when you subscribe on it in your component (or anywhere), http call will be executed and response will be returned in your subscribe section.




回答2:


You're returning a Subscription from your service (and thus your resolver), instead of returning an Observable. Don't subscribe in services. And specify return values, to avoid shooting yourself in the foot:

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

Note

  • the respect for naming conventions
  • the usage of GET to... get data, instead of POST
  • that the method defines what it actually returns
  • the usage of the generic overload of the HttpClient.get() method, which allows specifying the expected type of the response body
  • that having an instance fields in the service is wrong (and unnecessary).

Read the HttpClient guide, and the RxJS quide.




回答3:


Another way to get data from your backend is rather than subscribing to the data, you may also return back a promise and then use async await in your component

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

This will return back a promise to your component where you can also use in the following way:

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

  }
}


来源:https://stackoverflow.com/questions/55442164/how-to-return-httpclient-response-body-from-a-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!