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)
        }
      }
    }