javascript - Typescript ExpressJS - 将服务注入 REST API 控制器
问题描述
我正在尝试使用 Typescript 对我的 express rest API 使用 OOP 方法,并且在编写类时遇到问题。
这个想法是有一个 AuthController 类调用私有 AuthService 类来与数据库交互。但是,当我尝试使用 AuthController 类调用 AuthService 类时,它总是返回 undefined。
初始化我的快速应用程序并注册我的控制器的应用程序类:
class App {
private app;
private controllers: Controller[];
constructor(controllers: Controller[]) {
this.app = express();
this.controllers = controllers;
this.config();
this.initializeRoutes();
this.initializeErrorHandler();
}
config() {
console.log("running config");
this.app.use(cors());
this.app.use(express.json());
this.app.use(helmet());
}
public listen() {
this.app.listen(3000);
}
initializeRoutes() {
this.controllers.forEach((controller: any) => {
this.app.use("/", controller.router);
});
}
initializeErrorHandler() {
this.app.use(errorMiddleware);
}
}
(async () => {
try {
await connection(); //creates my database connection
} catch (error) {
console.log("Error while connecting to the database", error);
return error;
}
const app = new App([new AuthController()]);
app.listen();
})();
这是我的 AuthController 在我的调用中被初始化const app = new App([new AuthController()]);
export default class AuthController implements Controller {
public path = "/api/auth";
public router = Router();
private authService: AuthService = new AuthService();
constructor() {
this.initializeRoutes();
}
public initializeRoutes() {
//login route
this.router.post(this.path.concat("/login"), this.login);
this.router.post(
this.path.concat("/register"),
validationMiddleware(CreateUserDto),
this.register
);
this.router.post(this.path.concat("/resetpassword"), this.resetPassword);
this.router.post(this.path.concat("/newpassword"), this.newPassword);
}
public async register(req: Request, res: Response, next: NextFunction) {
const userData: CreateUserDto = req.body;
try {
let {
tokens: { xAuthToken, xRefreshToken },
user,
} = await this.authService.register(userData);
res.setHeader("x-auth-token", xAuthToken);
res.setHeader("x-refresh-token", xRefreshToken);
res.json(user);
} catch (e) {
next(e);
}
}
}
最后是 AuthService 类
export class AuthService {
private userRepo: Repository<User> = getRepository(User);
constructor() {}
public async register(userData: CreateUserDto) {
let foundUser = await this.userRepo.findOne({
where: { email: userData.email.toLowerCase() },
});
console.log(foundUser);
if (foundUser) {
throw new EmailInUseException();
} else {
console.log(foundUser);
const user = new User();
user.email = userData.email.toLowerCase();
user.password = userData.password;
await this.userRepo.save(user);
const tokens = this.createTokens(user);
return {
tokens,
user,
};
}
}
}
每当我从 AuthController 调用 AuthService 时,我都会收到“错误无法读取未定义的属性 'authService'”。
我尝试更改代码以直接初始化 AuthServiceconst app = new App([new AuthController(new AuthService()]);
但这并不能解决问题。
任何帮助表示赞赏!
解决方案
发现问题。'this' 上下文正在改变。我将我的“注册”方法切换为解决问题的箭头函数
原来的:
class AuthController{
public async register(req: Request, res: Response, next: NextFunction) {
const userData: CreateUserDto = req.body;
try {
let {
tokens: { xAuthToken, xRefreshToken },
user,
} = await this.authService.register(userData);
res.setHeader("x-auth-token", xAuthToken);
res.setHeader("x-refresh-token", xRefreshToken);
res.json(user);
} catch (e) {
next(e);
}
}
}
新的:
class AuthController{
public register = async (req: Request, res: Response, next: NextFunction) => {
const userData: CreateUserDto = req.body;
try {
let {
tokens: { xAuthToken, xRefreshToken },
user,
} = await this.authService.register(userData);
res.setHeader("x-auth-token", xAuthToken);
res.setHeader("x-refresh-token", xRefreshToken);
res.json(user);
} catch (e) {
next(e);
}
};
}