Search code examples
nestjsstringify

Why would it give JSON.stringfy error, even when I have not used it?


I am building application in nodejs where I have to display the data by hitting the HTTPS endpoint. I am using Swagger UI to display the data. I am getting following error

Converting circular structure to JSON +1169ms
TypeError: Converting circular structure to JSON
    at JSON.stringify (<anonymous>)
    at stringify (node_modules/express/lib/response.js:1123:12)
    at ServerResponse.json (node_modules/express/lib/response.js:260:14)
    at ExpressAdapter.reply (node_modules/@nestjs/platform-express/adapters/express-adapter.js:23:57)
    at RouterResponseController.apply (node_modules/@nestjs/core/router/router-response-controller.js:10:36)
    at @nestjs/core/router/router-execution-context.js:163:48
    at process._tickCallback (internal/process/next_tick.js:68:7)

even when I have not used JSON.stringfy in my code. How can I resolve this error? Here is my controller.ts code

import { Observable } from 'rxjs';

@Controller('/service/api/message')
export class MessageController {

  source: string;
  productCode: string;
  vehicleType: string;
  constructor(private messageService: MessageService) {}
@Post()
  @ApiUseTags('processor-dispatcher')
  @ApiOperation({ title: 'Generate product message for the SNS topics' })
  async generateMessage(@Body() productEvent: ProductEvent) {

    return this.messageService
      .getData(this.source, this.productCode, this.vehicleType)
      .subscribe(res => {
        console.log(res);
      });
  }
}

Here is my service.ts

import Axios, { AxiosResponse } from 'axios';

@Injectable()
export class MessageService {
  constructor(private readonly httpService: HttpService) {}

  configEndPoint: string =
    'https:www.xyz.com';


  getData(
    source: string,
    productCode: string,
    vehicleType: string,
  ): Observable<any> {
    return this.httpService.get(this.configEndPoint, { validateStatus: null });

  }
}


Solution

  • You shouldn't be subscribing to the observable, NestJS will handle that under the hood, just return the unsubscribed observable to the controller and let Nest handle it.

    The reason you are getting a JSON.stringify error, even though you aren't using it, is because express is using it under the hood in its send method. The AxiosResponse type (what the HttpService returns), has circular references to itself, so you need to not send the full response (it's a bad practice to return that entire response anyways, too much extra data). What you can do instead is use the map operator in a pipe to map which parts of the res you want to send back. Example

    @Injectable()
    export class MessageService {
      constructor(private readonly httpService: HttpService) {}
    
      configEndPoint: string =
        'https:www.xyz.com';
    
    
      getData(
        source: string,
        productCode: string,
        vehicleType: string,
      ): Observable<any> {
        return this.httpService.get(this.configEndPoint, { validateStatus: null }).pipe(
          map(res => res.data)
        );
      }
    }
    

    This will get the data property of the AxiosResponse and allow to only send that back.