Zana Daniel
Zana Daniel

Reputation: 301

How to return HttpClient response body from a request?

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

Upvotes: 1

Views: 3480

Answers (3)

hafridi
hafridi

Reputation: 278

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

  }
}

Upvotes: 1

Hemant Patel
Hemant Patel

Reputation: 3260

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.

Upvotes: 2

JB Nizet
JB Nizet

Reputation: 691715

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.

Upvotes: 4

Related Questions