I'm trying to call the REST API - such as https://randomuser.me/api/
and get the response logged and saved to a file in NestJS with Axios.
The rest call is in the Service class which is in turn is being accessed from the controller.
import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { AxiosResponse } from 'axios';
import { Observable} from 'rxjs';
import fs = require('fs')
import { map } from 'rxjs';
@Injectable()
export class RandomuserService {
constructor(
private httpService: HttpService
) {}
private logger = new Logger(RandomuserService.name)
// Send JSON Bundles to the FHIR Server
async getRandomuser(): Promise<Observable<AxiosResponse<any>>> {
try {
return this.httpService.get('https://randomuser.me/api/').pipe(map(response => response.data));
}
catch (err) {
this.logger.error(`Error in calling RandomUser RSET API end point: ${err}`)
}
}
.
.
// save the json response to file
writeToFile(data: any, fileName: string) {
...
}
}
And from the Controller
this getRandomuser()
is being accessed.
// Get Randomuser
@Get()
async getRandomuser(): Promise<any> {
try {
let result = await this.randomuserService.getRandomuser()
const jsonString = JSON.stringify(result, null, 2)
this.logger.log(`The Randomuser result1 : ${result}`)
this.logger.log(`The Randomuser result2 : ${jsonString}`)
return result
}
catch (err) {
this.logger.error(`Error in obatining the Randomuser result from RandomuserService class : ${err}`)
}
}
From the browser connecting to http://localhost:3333/
I get the response:
{"results":[{"gender":"male","name":{"title":"Monsieur","first":"Renzo","last":"Rousseau"},"location":{"street":{"number":5368,"name":"Rue Docteur-Bonhomme"},"city":"Nesslau","state":"Bern","country":"Switzerland","postcode":8221,"coordinates":{"latitude":"-55.2927","longitude":"-143.8486"},"timezone":{"offset":"-12:00","description":"Eniwetok, Kwajalein"}},"email":"[email protected]","login":{"uuid":"de08b93c-9879-40cd-9671-738dcc659eed","username":"lazybutterfly535","password":"glacier","salt":"JHBMcY2v","md5":"061daa26038881e9c554230d56d9cf17","sha1":"4e4ee22ffb6433599109a5a84d051f6812b21c01","sha256":"262d628c486f014c4be28456f74a56344f9a3fcce457541764e962b00601f393"},"dob":{"date":"1956-04-19T17:30:24.905Z","age":65},"registered":{"date":"2011-05-17T15:38:03.695Z","age":10},"phone":"078 336 99 84","cell":"079 578 23 53","id":{"name":"AVS","value":"756.8704.7049.02"},"picture":{"large":"https://randomuser.me/api/portraits/men/85.jpg","medium":"https://randomuser.me/api/portraits/med/men/85.jpg","thumbnail":"https://randomuser.me/api/portraits/thumb/men/85.jpg"},"nat":"CH"}],"info":{"seed":"dd592dab2501b022","results":1,"page":1,"version":"1.3"}}
However, I am getting the empty objects when I try to print the response in the Logger or Console.
Nest] 68352 - 11/05/2021, 4:07:45 PM LOG [RandomuserController] The Randomuser result1 : [object Object]
[Nest] 68352 - 11/05/2021, 4:07:45 PM LOG [RandomuserController] The Randomuser result2 : {
"source": {}
}
How should I log the complete response? How can I save the response to a file? (now it saves only {"source": {}}
)
Nest's HttpService
returns an RxJS Observable which is kind of like a supercharged callback. By default await
doesn't work on Observables, but Nest will handle the observable if you end up sending one back from your controller. To be able to await
the observable, you need to wrap the observable in the lastValueFrom
method from rxjs
. If you want to just use Observables for the entire call, then you need to make use of .pipe
and rxjs/operators
, probably tap
for logging. Something like this should do
@Get()
async getRandomuser(): Observable<any> {
return this.randomuserService.getRandomuser().pipe(
tap((data) => {
const jsonString = JSON.stringify(data, null, 2);
this.logger.log(`The Randomuser result1 : ${data}`)
this.logger.log(`The Randomuser result2 : ${jsonString}`)
}),
catchError(err => {
this.logger.error(`Error in obatining the Randomuser result from RandomuserService class : ${err}`)
throwError(err);
})
)
}