How should i import loginMember in Controller? I am developing as a REST API and now I need to use code in a different file location. I am having a error in controller. When i am calling loginMember.(Cannot find name 'loginMember'.ts(2304))
SERVICE
import MembersModel from '../models/MembersModel';
import BaseService from './BaseService';
import { createPasswordToHash } from '../scripts/utils/auth';
class MembersService extends BaseService {
constructor() {
super(MembersModel);
}
// loginMember
loginMember = async (email: any, password: any) => {
return new Promise(async (resolve, reject) => {
try {
let data = await this.BaseModel.findOne({
email: email,
password: createPasswordToHash(password),
});
return resolve(data);
} catch (error) {
return reject(error);
}
});
};
}
export default MembersService;
CONTROLLER
import BaseController from './BaseController';
import MembersService from '../services/MembersService';
import ApiError from '../errors/ApiError';
import { NextFunction, Request, Response } from 'express';
import { createPasswordToHash, generateAccessToken } from '../scripts/utils/auth';
import httpStatus from 'http-status';
class MembersController extends BaseController {
constructor(membersService: MembersService) {
super(membersService);
}
login = (req: Request, res: Response, next: NextFunction) => {
MembersService.loginMember(req.body)
.then((response: any) => {
if (response) {
const member = {
...response.toObject(),
accessToken: generateAccessToken(response.toObject()),
};
delete member.password;
delete member.createdAt;
delete member.updatedAt;
return res.status(httpStatus.OK).send(member);
}
return res.status(httpStatus.UNAUTHORIZED).send({ error: 'Invalid email or password' });
})
.catch((err: { message: string }) => {
return next(
new ApiError(err.message, httpStatus.UNAUTHORIZED, 'login', req.headers['user-agent']?.toString() || 'Unknown')
);
});
};
}
export default new MembersController(new MembersService());
Now i am gettig new error: "Property 'loginMember' does not exist on type 'typeof MembersService'.ts(2339)"
CodePudding user response:
You're trying to call loginMember
as a static method, but it's not defined as one. You'll have to use an instance of MembersService
to use the method. Since your MembersController
is already being initialized with a MembersService
instance, you may just want to have a membersService
property on the MembersController
. Also, the loginMember
method takes an email and a password, so you'll have to pass those arguments explicitly instead of just passing the request body. (I'm not sure where the email and password are in the request body though, so I can't help you there.) So with those changes, it would look like:
class MembersController extends BaseController {
private membersService: MembersService;
constructor(membersService: MembersService) {
super(membersService);
this.membersService = membersService;
}
login = (req: Request, res: Response, next: NextFunction) => {
this.membersService.loginMember(email, password) // <- Get these from the request
.then((response: any) => {
if (response) {
const member = {
...response.toObject(),
accessToken: generateAccessToken(response.toObject()),
};
delete member.password;
delete member.createdAt;
delete member.updatedAt;
return res.status(httpStatus.OK).send(member);
}
return res.status(httpStatus.UNAUTHORIZED).send({ error: 'Invalid email or password' });
})
.catch((err: { message: string }) => {
return next(
new ApiError(err.message, httpStatus.UNAUTHORIZED, 'login', req.headers['user-agent']?.toString() || 'Unknown')
);
});
};
One other code style suggestion would be to use async
await
instead of .then
in the login
method. Also, the Promise wrapping in the loginMember
method looks unnecessary, and using an async function as the argument is an antipattern. The following should get the job done while avoiding those pitfalls:
loginMember = (email: any, password: any): Promise<Response> => {
return this.BaseModel.findOne({
email: email,
password: createPasswordToHash(password),
});
};