Вопрос или проблема
Пожалуйста, я схожу с ума. В настоящее время я работаю над проектом базы данных с использованием PostGreSQL, Python Flask для бэкенда и HTML/CSS/Javascript для фронтенда. Но на одной из страниц, где должны быть две кнопки для создания отчетов, одна из них не работает, и при нажатии на нее появляется следующее сообщение об ошибке в “Просмотр кода”:
Uncaught (in promise) TypeError: Cannot read properties of null (reading ‘value’)
at fetchProdutoVendidoReport (script.js:50:61)
at HTMLButtonElement.onclick
И каждый раз, когда я пытаюсь это исправить, например, даю “id” элементам HTML формы, другая кнопка/запрос на той же странице не работает, и обе выдаёт 500: Internal Server Error.
Может кто-то помочь мне? Это тело HTML упомянутой страницы (я бразилец, поэтому многие вещи на португальском, но надеюсь, это не слишком сложно для понимания проблемы):
<body>
<div id="header"></div>
<script src="/frontend/components/header/header.js"></script>
<h1>Gerar Relatórios</h1>
<!-- Формуляр для отчета о заказе клиента -->
<h2>Relatório de Pedido Cliente</h2>
<form id="pedidoClienteForm">
<label>Categoria: <input type="text" id="categoria" name="categoria"></label><br>
<label>Data Mínima: <input type="date" id="startDate" name="data_min"></label><br>
<label>Data Máxima: <input type="date" id="endDate" name="data_max"></label><br>
<label>Fabricante: <input type="text" id="marca" name="fabricante"></label><br>
<label>Método de Pagamento: <input type="text" id="metodoPagamento" name="metodo"></label><br>
<label>Preço Mínimo: <input type="number" id="precoMin" name="preco_min"></label><br>
<label>Preço Máximo: <input type="number" id="precoMax" name="preco_max"></label><br>
<button type="button" onclick="fetchPedidoClienteReport()">Gerar Relatório de Pedido Cliente</button>
</form>
<div id="pedidoClienteResultado"></div>
<h2>Resultados</h2>
<table id="TabelaPedidoCliente">
<thead>
<tr>
<th>Produto</th>
<th>Categoria</th>
<th>Marca</th>
<th>Total Vendido</th>
<th>Receita Total</th>
<th>Método de Pagamento</th>
<th>Data de Venda</th>
</tr>
</thead>
<tbody></tbody>
</table>
<!-- Формуляр для отчета о проданном товаре -->
<h2>Relatório de Produto Vendido</h2>
<form id="produtoVendidoForm">
<label>Data Mínima: <input type="date" id="DataComeco" name="data_min"></label><br>
<label>Data Máxima: <input type="date" id="DataFinal" name="data_max"></label><br>
<label>Preço Mínimo: <input type="number" id="preco_Min" name="preco_min"></label><br>
<label>Preço Máximo: <input type="number" id="preco_Max" name="preco_max"></label><br>
<button type="button" onclick="fetchProdutoVendidoReport()">Gerar Relatório de Produto Vendido</button>
</form>
<div id="produtoVendidoResultado"></div>
<h2>Resultados</h2>
<table id="TabelaProdutoVendido">
<thead>
<tr>
<th>Produto</th>
<th>Faixa de Preço</th>
<th>Total Vendido</th>
<th>Receita Total</th>
<th>Método de Pagamento</th>
</tr>
</thead>
<tbody></tbody>
</table>
<script src="/frontend/pages/relatorios/script.js"></script>
</body>
А это JS:
async function fetchPedidoClienteReport() {
const startDate = document.getElementById('startDate').value;
const endDate = document.getElementById('endDate').value;
const categoria = document.getElementById('categoria').value;
const marca = document.getElementById('marca').value;
const precoMin = document.getElementById('precoMin').value;
const precoMax = document.getElementById('precoMax').value;
const metodoPagamento = document.getElementById('metodoPagamento').value;
const url = `http://127.0.0.1:8000/relatorio/pedido_cliente?categoria=${categoria}&data_min=${startDate}&data_max=${endDate}&fabricante=${marca}&metodo=${metodoPagamento}&preco_min=${precoMin}&preco_max=${precoMax}`;
try {
// Отправляет запрос на бэкенд
const response = await fetch(url, {
method: 'GET'
});
// Конвертирует ответ в JSON
const data = await response.json();
// Обновляет таблицу с данными
const tbody = document.getElementById('TabelaPedidoCliente').getElementsByTagName('tbody')[0];
// Очищает таблицу перед заполнением новыми данными
tbody.innerHTML = '';
function formataData(dateString) {
const date = new Date(dateString);
return date.toLocaleDateString('pt-BR'); // Формат 'DD/MM/YYYY'
}
// Заполняет таблицу данными отчета
data.forEach(item => {
const row = tbody.insertRow();
row.insertCell(0).textContent = item.nome; // имя товара
row.insertCell(1).textContent = item.categoria; // категория товара
row.insertCell(2).textContent = item.fabricante; // производитель товара
row.insertCell(3).textContent = item.quantidade; // всего продано
row.insertCell(4).textContent = item.total_venda; // общая выручка
row.insertCell(5).textContent = item.metodo; // метод оплаты
row.insertCell(6).textContent = formataData(item.data); // дата продажи
})
} catch (error) {
console.error('Ошибка при генерации отчета:', error);
}
}
// Функция для получения отчета о проданном товаре
async function fetchProdutoVendidoReport() {
const DataComeco = document.getElementById('DataComeco').value;
const DataFinal = document.getElementById('DataFinal').value;
const Preco_Min = document.getElementById('preco_Min').value;
const Preco_Max = document.getElementById('preco_Max').value;
const url = `http://127.0.0.1:8000/relatorio/produto_vendido?data_min=${DataComeco}&data_max=${DataFinal}&preco_min=${Preco_Min}&preco_max=${Preco_Max}`;
try {
// Отправляет запрос на бэкенд
const response = await fetch(url, {
method: 'GET'
});
// Конвертирует ответ в JSON
const data = await response.json();
// Обновляет таблицу с данными
const tbody = document.getElementById('TabelaProdutoVendido').getElementsByTagName('tbody')[0];
// Очищает таблицу перед заполнением новыми данными
tbody.innerHTML = '';
// Заполняет таблицу данными отчета
data.forEach(item => {
const row = tbody.insertRow();
row.insertCell(0).textContent = item.nome; // имя товара
row.insertCell(1).textContent = item.faixa_preco; // категория товара
row.insertCell(2).textContent = item.total_vendido; // производитель товара
row.insertCell(3).textContent = item.receita_total; // всего продано
row.insertCell(4).textContent = item.metodo; // метод оплаты
})
} catch (error) {
console.error('Ошибка при генерации отчета:', error);
}
}
Добавьте недостающие идентификаторы во втором формуляре.
<form id="produtoVendidoForm">
<label>Data Mínima: <input type="date" id="DataComeco" name="data_min"></label><br>
<label>Data Máxima: <input type="date" id="DataFinal" name="data_max"></label><br>
<label>Preço Mínimo: <input type="number" id="preco_Min" name="preco_min"></label><br>
<label>Preço Máximo: <input type="number" id="preco_Max" name="preco_max"></label><br>
<button type="button" onclick="fetchProdutoVendidoReport()">Gerar Relatório de Produto Vendido</button>
</form>
Ответ или решение
Введение
В процессе разработки баз данных с использованием PostgreSQL и Flask, тревожные ситуации, как неработающие кнопки и ошибки сервера, могут озадачивать даже опытных разработчиков. Давайте разберем проблему с кнопкой "Gerar Relatório de Produto Vendido", которая вызывает ошибку при попытке получения отчета, и сколько различных факторов может влиять на это.
Проблема
Ошибка Uncaught (in promise) TypeError: Cannot read properties of null (reading 'value')
говорит о том, что JavaScript не может найти элемент с указанным id
. Это означает, что когда пользователь нажимает на кнопку, функция fetchProdutoVendidoReport
пытается получить значение переменных, привязанных к элементам формы, которые не существуют.
Анализ HTML и JavaScript кода
Исходный HTML код для формы отчета о проданных товарах выглядит следующим образом:
<form id="produtoVendidoForm">
<label>Data Mínima: <input type="date" name="data_min"></label><br>
<label>Data Máxima: <input type="date" name="data_max"></label><br>
<label>Preço Mínimo: <input type="number" name="preco_min"></label><br>
<label>Preço Máximo: <input type="number" name="preco_max"></label><br>
<button type="button" onclick="fetchProdutoVendidoReport()">Gerar Relatório de Produto Vendido</button>
</form>
Функция JavaScript, которая вызывает ошибку, содержит следующие строки:
const DataComeco = document.getElementById('DataComeco').value;
const DataFinal = document.getElementById('DataFinal').value;
const Preco_Min = document.getElementById('preco_Min').value;
const Preco_Max = document.getElementById('preco_Max').value;
Решение проблемы
Когда элементы формы не имеют уникальных идентификаторов (id), связанные с ними значения не могут быть извлечены, что приводит к вышеупомянутой ошибке. В вашей форме produtoVendidoForm
отсутствуют id
для полей ввода. Чтобы исправить это, добавьте недостающие id
, как показано ниже:
<form id="produtoVendidoForm">
<label>Data Mínima: <input type="date" id="DataComeco" name="data_min"></label><br>
<label>Data Máxima: <input type="date" id="DataFinal" name="data_max"></label><br>
<label>Preço Mínimo: <input type="number" id="preco_Min" name="preco_min"></label><br>
<label>Preço Máximo: <input type="number" id="preco_Max" name="preco_max"></label><br>
<button type="button" onclick="fetchProdutoVendidoReport()">Gerar Relatório de Produto Vendido</button>
</form>
Теперь функция fetchProdutoVendidoReport
сможет корректно получать значения из формы.
Обработка Ошибок Серверной Часть
Ошибки 500 (Internal Server Error) чаще всего указывают на проблему на стороне сервера. Убедитесь в следующем:
-
Корректные маршруты в Flask: Убедитесь, что URL, передаваемые в запросе, правильно настроены в вашем Flask приложении. Пример:
@app.route('/relatorio/produto_vendido', methods=['GET']) def produto_vendido(): # Ваш код обработки запроса
-
Логи: Проверьте логи вашего приложения Flask для дополнительных подсказок о том, что именно вызывает ошибку сервера.
-
Формат данных: Убедитесь, что данные, полученные на сервере, соответствуют предполагаемому формату.
Заключение
Сложности при разработке сложных веб-приложений могут вызывать стрессы, однако шаги, описанные в этой статье, помогут вам найти и устранить многие распространенные ошибки. Добавление недостающих id
в форму должно устранить вашу первоначальную ошибку, тогда как проверка на стороне сервера поможет избежать 500 ошибок. Удачной разработки!