Home > OS >  How do I put the Service in the Controller constructor using typescript?
How do I put the Service in the Controller constructor using typescript?

Time:12-28

I'm making a simple REST API with typescript that calls your classes to check a database in this order: Controller > Service > Repository.

So I tried these codes:

Controller:

export class GetNurseController {
  constructor(private getNurseService: GetNurseService) {}

  async handle(req: Request, res: Response): Promise<Response> {
    try {
      const { id } = req.authrocket.currentUser;
      const user = await this.getNurseService.execute(id);

      return res.json({ user });
    } catch (err: any) {
      return res.status(500).json({ err });
      // That json return an empty err object, but in my console, an undefined error for
      // "getNurseService" is printed.
    }
  }
}

Router:

const nurseRepository = new NurseRepository();
const getNurseService = new GetNurseService(nurseRepository);
const getNurseController = new GetNurseController(getNurseService);

const nurseRoutes = Router();
nurseRoutes.get('/', requireLogin, getNurseController.handle);

I also tried this Controller:

export class GetNurseController {
  public NurseRepository: INurseRepository;
  public getNurseService: GetNurseService;

  constructor() {
    this.nurseRepository = new NurseRepository();
    this.getNurseService = new GetNurseService(this.nurseRepository);
  }

  async handle(req: Request, res: Response): Promise<Response> {
    try {
      const { id } = req.authrocket.currentUser;
      const user = await this.getNurseService.execute(id);

      return res.json({ user });
    } catch (err: any) {
      return res.status(500).json({ err });
    }
  }
}

When I try to access this route with code like this I always get an empty error or sometimes my browser refuses the connection.

But, when I change the code to this:

Controller:

export class GetNurseController {
  async handle(req: Request, res: Response): Promise<Response> {
    try {
      const nurseRepository = new nurseRepository();
      const getNurseService = new GetNurseService(nurseRepository);

      const { id } = req.authrocket.currentUser;
      const user = await getNurseService.execute(id);

      return res.json({ user });
    } catch (err: any) {
      return res.status(500).json({ err });
    }
  }
}

Router:

const getNurseController = new GetNurseController();

const nurseRoutes = Router();
nurseRoutes.get('/', requireLogin, getNurseController.handle);

Works well. Can someone explain to me what I'm doing wrong, or if what I'm trying to do is possible, please?

CodePudding user response:

My best guess is that the issue is how you pass the handler. You're doing that in a way that loses its reference to this.

Instead of this line:

nurseRoutes.get('/', requireLogin, getNurseController.handle);

You need either one of these:

nurseRoutes.get(
  '/',
  requireLogin,
  getNurseController.handle.bind(getNurseController)
);
nurseRoutes.get(
  '/',
  requireLogin,
  (req: Request, res: Response) => getNurseController.handle(req, res)
);
  • Related