user14451038
user14451038

Reputation:

How to send 2 HTTP requests in NestJS with built-in HttpService

I'd like to send 2 requests at the same time when one of my NestJS endpoints are called. I'm using Cloudant, and with the endpoint call I'd like to reach and do something with 2 different documents in 2 different databases. To be exact, I want to create a new document in one of the databases and modify another already existing document in another database.

This is the endpoint in my controller:

@Put()
createEntry(@Body() body: { title: string; description: string }): Observable<{ ok: boolean; id: string; rev: string }> {
  return this.entriesService.createEntry(body);
}

This is my entriesService:

createEntry(body: Entry): Observable<{ ok: boolean; id: string; rev: string }> {
  this.userService.modifyOtherDocument(body); // I'd like to execute this here
  return this.httpService.put(`${environment.cloudantBaseUrl}/entries/${uuidv4()}`, body).pipe(map((response) => response.data));
}

This method should call another method in another service, called userService like this:

modifyOtherDocument(body: Entry): Observable<{ ok: boolean; id: string; rev: string }> {
  return this.httpService.put(`${environment.cloudantBaseUrl}/other_db/${body.id}`, body).pipe(map((response) => response.data));
}

Both service methods work perfectly if I call them separately. But as soon as I want to call the other method in my userService from my entriesService method the document in other_db won't be updated at all.

How should I make this working? I'm using NestJS' built-in HttpService from @nestjs/axios. It doesn't matter in which order they'll be executed.

Upvotes: 0

Views: 1540

Answers (1)

Jay McDoniel
Jay McDoniel

Reputation: 70131

Nest's HttpService uses Observables from RxJS. They're kind of like callbacks, but don't fire until there's something actually observing it, whether this is a .subscribe() or a lastValueFrom method. What you can do here is make use of the Observable pipeline like so and have both events fired one after the other

createEntry(body: Entry): Observable<{ ok: boolean; id: string; rev: string }> {
  return this.userService.modifyOtherDocument(body).pipe(
    switchMap(() => this.httpService.put(`${environment.cloudantBaseUrl}/entries/${uuidv4()}`, body)),
    map((response) => response.data))
  );
}

This will make the first observable resolve and then call the second one to take its place. learnrxjs.io has some good resources on learning RxJS if you're interested

Upvotes: 1

Related Questions