Using NestJS Axios, a simple http get request throws "Cannot read properties of undefined (reading 'emit')" error

1k Views Asked by At

Versions I'm using in my NestJS project (I show just the relevant packages):

  • "@nestjs/common": "^9.4.0",
  • "@nestjs/axios": "^2.0.0",
  • "axios": "^1.3.6",
  • "follow-redirects": "^1.15.2",

I've tried to follow the documentation here from the beginning: https://docs.nestjs.com/techniques/http-module

I've created a module called geo.module.ts, which looks like this:

import { Module } from '@nestjs/common';
import { GeoService } from './geo.service';
import { GeoController } from './geo.controller';
import { HttpModule } from '@nestjs/axios';

@Module({
  imports: [HttpModule.register({
    timeout: 5000,
    maxRedirects: 5,
  })],
  controllers: [GeoController],
  providers: [GeoService]
})
export class GeoModule {}

Created the controller which points to the service that's fine, and here is the service:

import { HttpService } from '@nestjs/axios';
import { Injectable } from '@nestjs/common';

@Injectable()
export class GeoService {

  constructor(private readonly httpService: HttpService) {}

  findSomething() {
    return this.httpService.get('http://urldoesntmatter.something');
  }
}

This function runs, and throws an error like this:

[Nest] 424  - 2023. 04. 27. 7:49:48   ERROR [ExceptionsHandler] Cannot read properties of undefined (reading 'emit')
TypeError: Cannot read properties of undefined (reading 'emit')
    at Object.eventHandlers.<computed> [as abort] (C:\somewhere\node_modules\follow-redirects\index.js:14:24)
    at TransformOperationExecutor.transform (C:\somewhere\node_modules\src\TransformOperationExecutor.ts:207:39)      
    at TransformOperationExecutor.transform (C:\somewhere\node_modules\src\TransformOperationExecutor.ts:327:31)      
    at TransformOperationExecutor.transform (C:\somewhere\node_modules\src\TransformOperationExecutor.ts:327:31)      
    at TransformOperationExecutor.transform (C:\somewhere\node_modules\src\TransformOperationExecutor.ts:327:31)

This error is true for any url I enter. I've googled it all day but can not resolve this issue why this happens, seems like based on the doc I didn't miss anything.

  • Maybe the versions aren't compactible with each other?
  • I've already tried to downgrade "follow-redirects" package also "axios" package, didn't work.
  • Already tried to use directly "axios" package, also tried to use axiosRef as well. Tried different urls but even on my locally running apis it throws this error.
  • Tried to modify the module to set "maxRedirects: 5" to 0. In this case there is a different error, and I also don't want to modify that value also it is 5 by default.
  • Tried to modify url to use https instead of http, no success. I've checked the file as well where the error happens but I still couldn't figure out the issue.
2

There are 2 best solutions below

0
Adam Eros On

I've figured out.

Based on THIS answer, I've just returning the data itself instead of the entire Axios object. This finally resolve the problem. (but this isn't in the doc. :) )

So the updated code will look like this:

import { HttpService } from '@nestjs/axios';
import { Injectable } from '@nestjs/common';

@Injectable()
export class GeoService {

  constructor(private readonly httpService: HttpService) {}

  findSomething() {
    return this.httpService.get('http://urldoesntmatter.something').pipe(
       map(response => response.data)
    );
  }
}

Thanks for your time if you already have a look and tried to resolve the problem.

0
Kerimberdi Agayev On

Here is a full example from NestJs documentation which worked for me:

Since the return value of the HttpService methods is an Observable, we can use rxjs - firstValueFrom or lastValueFrom to retrieve the data of the request in the form of a promise.

import {
  catchError,
  firstValueFrom
} from 'rxjs';

@Injectable()
export class CatsService {
  private readonly logger = new Logger(CatsService.name);
  constructor(private readonly httpService: HttpService) {}

  async findAll(): Promise < Cat[] > {
    const {
      data
    } = await firstValueFrom(
      this.httpService.get < Cat[] > ('http://localhost:3000/cats').pipe(
        catchError((error: AxiosError) => {
          this.logger.error(error.response.data);
          throw 'An error happened!';
        }),
      ),
    );
    return data;
  }
}