Search code examples
node.jstypescriptexpressinversifyjs

Error with responses on nodejs using inversifyjs


I'm using nodejs with typescript, typeorm and inversify to manage dependency injection and inversify express utils to handle controllers, when I send a response inside then or catch block only returns a 204 no content response, but if I send the response out of the promise it works, someone who has worked with inversify know what could be happening?

User Controller:

@controller("/user")
export class UserController implements interfaces.Controller {
  constructor(@inject(TYPES.UserService) private _userService: IUserService) {}

  @httpGet("/")
  public GetAll(@request() req: Request, @response() res: Response) {
    this._userService
      .GetAll()
      .then((users) => res.send(users))
      .catch((error) => res.send(error));
  }
}

User Service:

@injectable()
export class UserService implements IUserService {
  private readonly _userRepository: IUserRepository;

  constructor(@inject(TYPES.UserRepository) userRepository: IUserRepository) {
    this._userRepository = userRepository;
  }

  public GetAll(): Promise<Array<User>> {
    return this._userRepository.GetAll();
  }
}

User repository:

@injectable()
export class UserRepository implements IUserRepository {
  public GetAll(): Promise<Array<User>> {
    const userRepository = getRepository(User);

    return userRepository.find();
  }

Container and server config:

export abstract class ServerConfig {
  protected app: Application;

  constructor() {
    this.Config();
  }

  private Config(): void {
    const container = new Container();

    container.bind<IUserService>(TYPES.UserService).to(UserService);
    container.bind<IUserRepository>(TYPES.UserRepository).to(UserRepository);

    const server = new InversifyExpressServer(container);

    server.setConfig((app) => {
      app.use(cors());
      app.use(helmet());
      app.use(express.urlencoded({ extended: true }));
      app.use(express.json());
      app.use(morgan("dev"));
      dotenv.config();
      app.set("port", process.env.PORT || 8000);
    });

    this.app = server.build();
  }

  public Start(): void {
    this.app.listen(this.app.get("port"), () => {
      console.log(`Server on port ${this.app.get("port")}`);
    });
  }
}

Solution

  • you need to return the promise or just await the response from the service. Something like this:

    @controller("/user")
    export class UserController implements interfaces.Controller {
     constructor(@inject(TYPES.UserService) private _userService: IUserService) {}
    
      @httpGet("/")
      public async GetAll(@request() req: Request, @response() res: Response): Response {
        try {
          const users = await this._userService.GetAll();
          return res.status(200).json(users);
        } catch(error) {
          return res.status(500).json(error)
        }
      }
    }