Ошибка “Не определено” в проекте Node.js + Express.js + Ejs

Вопрос или проблема

Я создаю веб-сайт на основе node.js (express.js), MYSQL и Ejs.

Я пытался отобразить график с помощью d3.js.

Это часть скрипта в mainpage.ejs

    <script src="https://d3js.org/d3.v6.min.js"></script>
    <script>

        const yearData = <%- JSON.stringify(yearData) %>;

        const yearChartWidth = 600;
        const yearChartHeight = 400;
        const margin = { top: 20, right: 20, bottom: 30, left: 40 };

        const svg = d3.select('#yearChart')
            .append('svg')
            .attr('width', yearChartWidth + margin.left + margin.right)
            .attr('height', yearChartHeight + margin.top + margin.bottom)
            .append('g')
            .attr('transform', `translate(${margin.left}, ${margin.top})`);

        const xScale = d3.scaleBand()
            .domain(yearData.map(d => d.year))
            .range([0, yearChartWidth])
            .padding(0.1);

        const yScale = d3.scaleLinear()
            .domain([0, d3.max(yearData, d => d.count)])
            .range([yearChartHeight, 0]);

        svg.selectAll('.bar')
            .data(yearData)
            .enter()
            .append('rect')
            .attr('class', 'bar')
            .attr('x', d => xScale(d.year))
            .attr('y', d => yScale(d.count))
            .attr('width', xScale.bandwidth())
            .attr('height', d => yearChartHeight - yScale(d.count))
            .attr('fill', 'steelblue');

        svg.append('g')
            .attr('transform', `translate(0, ${yearChartHeight})`)
            .call(d3.axisBottom(xScale));

        svg.append('g')
            .call(d3.axisLeft(yScale));
    </script>

А это часть серверного кода, server.js

app.get("https://stackoverflow.com/", (req, res) => {

  const yearQuery = `SELECT release_year, COUNT(*) AS count FROM movies GROUP BY release_year`;

  let yd = [];

  connection.query(yearQuery, (err, yearResults) => {
    if (err) {
      console.error('Ошибка при получении данных по годам:', err);
      return res.status(500).send('Внутренняя ошибка сервера');
    }

    yd = yearResults.map(row => ({
      year: row.release_year,
      count: row.count
    }));

    res.render('mainpage', { yearData: yd, session: req.session });
  });
});

И затем я получаю следующий код ошибки:

ReferenceError: C:\Users\harry\Desktop\IWD Assignment\views\mainpage.ejs:78
    76|     <script>

    77|         

 >> 78|         const yearData = <%- JSON.stringify(yearData) %>;

    79| 

    80|         

    81|         const yearChartWidth = 600;

yearData не определена
    at eval (eval at compile (C:\Users\harry\Desktop\IWD Assignment\node_modules\ejs\lib\ejs.js:673:12), <anonymous>:30:32)
    at mainpage (C:\Users\harry\Desktop\IWD Assignment\node_modules\ejs\lib\ejs.js:703:17)
    at tryHandleCache (C:\Users\harry\Desktop\IWD Assignment\node_modules\ejs\lib\ejs.js:274:36)
    at exports.renderFile [as engine] (C:\Users\harry\Desktop\IWD Assignment\node_modules\ejs\lib\ejs.js:491:10)
    at View.render (C:\Users\harry\Desktop\IWD Assignment\node_modules\express\lib\view.js:135:8)
    at tryRender (C:\Users\harry\Desktop\IWD Assignment\node_modules\express\lib\application.js:657:10)
    at Function.render (C:\Users\harry\Desktop\IWD Assignment\node_modules\express\lib\application.js:609:3)
    at ServerResponse.render (C:\Users\harry\Desktop\IWD Assignment\node_modules\express\lib\response.js:1049:7)
    at C:\Users\harry\Desktop\IWD Assignment\server.js:61:7
    at Layer.handle [as handle_request] (C:\Users\harry\Desktop\IWD Assignment\node_modules\express\lib\router\layer.js:95:5)

Я думал, что проблема вызвана неправильным соединением переменных, однако я не смог найти, где я неправильно настроил код.

Можете ли вы найти любую ошибку, которая вызывает проблему?

Я думал, что проблема вызвана неправильным соединением переменных, однако я не смог найти, где я неправильно настроил код. (Я изменял часть res.render() в server.js, но ошибка осталась.)

Можете ли вы найти любую ошибку, которая вызывает проблему?

Это похоже на проблему с вашей настройкой EJS. Вам нужно добавить это в начале файла server.js. Если это не сделать, переменная yearData не будет передана в представление.

const path = require('path');
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
your-project/
  ├── server.js
  ├── views/
  │   └── mainpage.ejs
  ├── node_modules/
  └── package.json

Пожалуйста, сообщите, если проблема сохраняется после этого

Ответ или решение

Ответ на проблему "Not defined" в проекте Node.js с Express.js и EJS

Вам необходимо удостовериться, что переменная yearData правильно передается во вьюху (EJS), чтобы избежать ошибки "yearData is not defined". Давайте разберем, что может быть не так.

1. Настройки EJS

Убедитесь, что у вас правильно настроен EJS как движок шаблонов. В верхней части вашего файла server.js должно быть что-то вроде следующего:

const path = require('path');
const express = require('express');
const app = express();

// Настройка EJS как движка представления
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));

// Ваши маршруты здесь...

Это позволит Express находить ваши файлы шаблонов EJS.

2. Проверьте маршрут

Убедитесь, что ваш маршрут возвращает данные правильно. Судя по вашему коду, вы правильно извлекаете данные из базы данных и передаете их в метод res.render. Ваш текущий маршрут выглядит корректно:

app.get("/", (req, res) => { // измените на правильный URL для вашего приложения
    const yearQuery = `SELECT release_year, COUNT(*) AS count FROM movies GROUP BY release_year`;
    let yd = [];

    connection.query(yearQuery, (err, yearResults) => {
        if (err) {
            console.error('Error fetching year data:', err);
            return res.status(500).send('Internal Server Error');
        }

        yd = yearResults.map(row => ({
            year: row.release_year,
            count: row.count
        }));

        res.render('mainpage', { yearData: yd, session: req.session });
    });
});

Убедитесь, что ваш запрос к базе данных выполняется правильно, и переменная yd успешно заполняется.

3. Использование в EJS

В вашем шаблоне EJS проверьте, что вы правильно используете синтаксис EJS для вставки данных:

<script>
    const yearData = <%- JSON.stringify(yearData) %>;
</script>

Используйте <%- ... %>, чтобы избежать экранирования, так как yearData является объектом JavaScript, который вы хотите преобразовать в строку JSON.

Пример структуры проекта

Убедитесь, что ваша структура проекта выглядит правильно:

your-project/
  ├── server.js
  ├── views/
  │   └── mainpage.ejs
  ├── node_modules/
  └── package.json

Заключение

Если следуя этим шагам проблема устранена не была, убедитесь, что:

  • yearData существует и правильно передается из сервера на клиент.
  • Ваша база данных возвращает ожидаемые данные.
  • Вы не опечатались в именах переменных.

Если вы все настроили правильно, то ошибка "yearData is not defined" должна исчезнуть. Если проблема все еще присутствует, пожалуйста, предоставьте дополнительную информацию о коде или конфигурации, чтобы можно было глубже разобраться в вашей проблеме.

Оцените материал
Добавить комментарий

Капча загружается...