Не считывается переменная из constructor
В expressjs используется промежуточный слой для обработки входях вызовов через класс
/middlewares/index.js
class Middlewares {
constructor(options) {
this.options = options;
}
general(req, res, next) {
console.log(this.options)
}
test() {
console.log(this.options)
}
}
export default Middlewares;
В app.js
import express from 'express';
import { createServer } from 'http';
import Middlewares from './middlewares/index.js'
const app = express();
const options = {
whiteListSite: ['http://localhost:81', 'http://localhost:83'],
};
const server = createServer(app);
const middlewares = new Middlewares(options);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(middlewares.general); //<-- получаю ошибку TypeError: Cannot read properties of undefined (reading 'options')
middlewares.test() //<-- здесь срабатывает все, в консоль выводиться { whiteListSite: [ 'http://localhost:81', 'http://localhost:83' ] }
app.get('/', function(req, res) {
res.send('hello world');
});
server.listen(8080, () => {
console.log(`GateWay app listening on port ${8080}`);
});
В ходе работы сервера, когда срабатывает обработчик т.е при любом запросе по роутам, в функции general
выдаётся ошибка TypeError: Cannot read properties of undefined (reading 'options')
, но когда вызываю test() все хорошо работает без сбоев
Т.е функция из класса не может получить переменную из конструктора класса. С чем это связано?
Ответы (1 шт):
Ошибка связана с потерей контекста вызова
Так же вы забыли вызвать функцию next(), которая активирует следующую функцию промежуточной обработки в приложении.
Для устранения ошибки, предложу пару способов
Первый, использовать замыкания и передавать this в отдельной переменной
general() {
const self = this // Присваиваем this отдельной переменной
// Возвращаем новую функцию
return function (req, res, next) {
console.log(self.options)
next()
}
}
/* остальной код */
// Передаем результат работы метода general
app.use(middlewares.general())
Второй, использовать стрелочную функцию, т.к. они не обладают собственным контекстом
general = (req, res, next) => {
console.log(this.options)
next()
}
/* остальной код */
// Передаем сам метод general
app.use(middlewares.general)
Можно конечно еще привязать в явном виде контекст к вашему варианту метода general
app.use(middlewares.general.bind(middlewares))
однако мне этот способ не очень нравится