I have a problem trying to access to "service" property inside a controller method. I receive the error "Cannot read properties of undefined (reading "service")".
I can't understand why because within my service I have declared a property in the same way and it works.
this is my service:
export default class StaffService {
private daoStaff: StaffDao;
constructor() {
this.daoStaff = new StaffDao();
}
async login(username: string, password: string) {
const checkUser = await this.daoStaff.findByUsername(username);
if (!checkUser) throw new Error("INVALID_CREDENTIALS");
return await this.daoStaff.login(username, password);
}
}
when I run tests on the service it works perfectly.
this is my controller:
export default class StaffController {
private service: StaffService;
constructor() {
this.service = new StaffService();
}
async login (req: Request, res: Response){
try {
const { username, password } = req.body;
const resService = await this.service.login(username, password);
return res
.status(200)
.json(new ResponseEntity(200, "LOGIN_SUCCESSFULLY", resService));
} catch (e: unknown) {
if (e instanceof Error) {
switch (e.message) {
case "INVALID_CREDENTIALS":
return res
.status(400)
.json(new ResponseEntity(400, e.message, null));
default:
return res
.status(500)
.json(new ResponseEntity(500, e.message, null));
}
}
}
};
}
when I run tests on the controller I get the error "Cannot read properties of undefined (reading "service")".
I have tried some solutions such as:
Converting the method to an arrow function and it works, but I don't know if this is a good practice.
login = async (req: Request, res: Response) => {
try {
const { username, password } = req.body;
const resService = await this.service.login(username, password);
return res
.status(200)
.json(new ResponseEntity(200, "LOGIN_SUCCESSFULLY", resService));
} catch (e: unknown) {
if (e instanceof Error) {
switch (e.message) {
case "INVALID_CREDENTIALS":
return res
.status(400)
.json(new ResponseEntity(400, e.message, null));
default:
return res
.status(500)
.json(new ResponseEntity(500, e.message, null));
}
}
}
};
Another solution that worked was to do a .bind() in the constructor() for the method and that also worked, but my controller has more than 10 methods and I would have to bin each of the methods and I don't know if that is good practice either.
What is the best solution to this problem? What am I doing wrong?