я переношу свое приложение node.js на typescript и впервые делаю это, по какой-то причине после объявления и создания моего класса, когда я создаю новый экземпляр экземпляра класса моего контроллера класса, получаю эту ошибку после создания запрос к конечной точке:
TypeError: Cannot read property 'utilities' of undefined
at getCategories (C:\Users\Migue\Desktop\movie-arcade-backend\src\controllers\categories.controller.ts:19:34)
Утилиты
export default class Utilities {
constructor() {}
mapFavorities(favorites: Movie[]) {
if (!favorites || favorites.length === 0) {
return [];
}
return favorites.map((f) => {
return {
_id: f._id,
new: f.new,
rate: f.rate,
content_type: f.content_type,
name: f.name,
cover: f.cover,
release_date: f.release_date,
created: f.created,
updateOn: f.updateOn,
item_type: f.item_type,
comments: f.comments,
};
});
}
mapPageParams(req: Request) {
const params: any = {};
Object.keys(req.query).forEach((key) => {
params[`${key}`] = req.query[`${key}`] === 'undefined' ? undefined : req.query[`${key}`];
});
if (params.sortBy) {
params['sort'] = {
[`${params.sortBy}`]: `${params.direction}`,
};
}
return params;
}
isValidToken(req: Request) {
const token = req.headers.authorization.split(' ')[1];
if (token) {
try {
jwt.verify(token, process.env.SECRET);
return true;
} catch (error) {
return false;
}
}
return false;
}
isAuthenticated(req: Request) {
return !!req.headers.authorization && !!req.headers.authorization.split(' ')[1];
}
decodeToken(req: Request) {
const token = req.headers.authorization.split(' ')[1];
try {
return this.isAuthenticated(req) && this.isValidToken(req) ? jwt.decode(token) : undefined;
} catch (error) {
return undefined;
}
}
getRole(req: Request) {
const userToken: any = this.decodeToken(req);
return userToken ? userToken.auth_rol : undefined;
}
generateImgPath(req: Request, imgFile?: any) {
return `${req.protocol}://${req.get('host')}/images/${imgFile ? imgFile.filename : req.file.filename}`;
}
getImageName(image: string) {
return image.split('images/')[1];
}
fileExist(file: string) {
return fs.existsSync(`./images/${file}`);
}
deleteFileFromFs(file: string) {
fs.unlinkSync(`./images/${file}`);
}
}
категория.контроллер
import Utilities from '../utilities/utilities';
export default class CategoryController {
private readonly utilities: Utilities = new Utilities();
private readonly movieAdapter: MovieAdapter = new MovieAdapter();
private readonly categoryAdapter: CategoryAdapter = new CategoryAdapter();
constructor() {}
getCategories(req: Request, res: Response) {
const pageQueryParams = this.utilities.mapPageParams(req);
if (pageQueryParams.page) {
Category.countDocuments({}, (error, count) => {
if (error) {
return res.status(500).send(error);
}
from(
Category.find()
.skip(+pageQueryParams.pageSize * +pageQueryParams.page - +pageQueryParams.pageSize)
.limit(+pageQueryParams.pageSize)
.sort(pageQueryParams.sort)
).subscribe(
(list) => {
res.status(200).send({ count, list });
},
(error) => {
res.send(error);
}
);
});
} else {
from(Category.find()).subscribe(
(list) => {
res.status(200).send(list);
},
(error) => {
res.status(500).send(error);
}
);
}
}
маршруты
export const router = express.Router();
const authMiddleWare = new AuthMiddleWare();
const categoryController = new CategoryController();
/* Get all the categories */
router.get('/', categoryController.getCategories);
/* Get single Category */
router.get('/:id', authMiddleWare.checkAuth, authMiddleWare.checkRole, categoryController.getSingleCategory);
/* Create a new category */
router.post('/', authMiddleWare.checkAuth, authMiddleWare.checkRole, categoryController.createCategory);
/* Update a category */
router.put('/:id', authMiddleWare.checkAuth, authMiddleWare.checkRole, categoryController.updateCategory);
/* Delete a category */
router.delete('/:id', authMiddleWare.checkAuth, authMiddleWare.checkRole, categoryController.removeCategory);
/* Get items by category */
router.get('/category/:name', categoryController.getItemsByCategory);
Проблема в том, что this
есть undefined
, поскольку вы передаете ссылку на функцию categoryController.getCategories
, а не на сам контекст класса. Вместо этого сделайте следующее:
router.get('/', categoryController.getCategories.bind(categoryController);
В качестве альтернативы вы можете связать getCategories
внутри конструктора CategoryController
.
Нашел способ сделать это, спасибо за ответ :)
Да, это было решением, большое спасибо, всего один маленький вопрос, как я могу реорганизовать свой класс, чтобы не использовать привязку...?