使用NodeJs、Express和Ejs文件创建的API在第二次尝试从数据库获取数据时崩溃

11dmarpk  于 2023-06-22  发布在  Node.js
关注(0)|答案(1)|浏览(134)

我的任务是创建一个API,从数据库中获取数据并使用前端显示它。这是我第一次接触到创建API,并且一直在努力。该数据库被称为fitnessTracker,它包括4个表userfit,exercises,workout和workoutExercises。对于我在Visual Studio中的API,我有以下'main'文件:server.js、routes.js、controller.js、queries.js、db.js、index.ejs(作为主模板)、exercises.ejs和userfit.ejs当前我在queries.js中的查询在我的ejs文件上产生了完美的结果,然而,在第二次尝试这样做时,服务器崩溃/停止。
为了演示,我在queries.js中有一个查询,它通过ID获取练习,如下所示:const getExerciseById = "SELECT * FROM exercises WHERE exercise_id = $1";,然后导出。
在我的controller.js文件中,我有以下代码来方便上述查询:

const getExerciseById = (req, res) => {
  const exercise_id = parseInt(req.params.exercise_id);
  pool.query(queries.getExerciseById, [exercise_id], (error, results) => {
    if (error) throw error;
    res.render('exercises', { exercises: results.rows });
  });
};

然后输出
在我的routes.js文件中,我有以下路由,其中最后一个路由便于上面的查询:

const express = require('express');
const controller = require('./controller');
const router = express.Router();

router.get("/", controller.getUsers);
router.get("/userfit/id/:user_id", controller.getUserById);
router.get("/userfit/username/:username", controller.getUsersByUsername);
router.get("/userfit/emails/:email", controller.getUsersByEmail);
router.get("/userfit/genders/:gender", controller.getUsersByGender);
router.get("/userfit/heights/:minHeight/:maxHeight", controller.getUsersByHeightRange);
router.get("/userfit/weights/:minWeight/:maxWeight", controller.getUsersByWeightRange);

router.get("/exercises", controller.getExercises);
router.get("/exercises/e_id/:exercise_id", controller.getExerciseById);

然后导出路由器,
在我的index.ejs文件中,我有以下代码来简化和显示上述查询的结果:

<li>
      <form id="exercises-id-form">
        <label for="exercise_id">Search Exercise By ID:</label>
        <input type="text" id="exercise_id" name="exercise_id">
        <button type="submit">Submit</button>
      </form>
    </li>
<script>
      $(document).ready(function() {
        $('#exercises-id-form').submit(function(event) {
          event.preventDefault();
          const exercise_id = $('#exercise_id').val();
          window.location.href = `/api/v1/fitness_tracker/exercises/e_id/${exercise_id}`;
        });
      });
    </script>

现在,每当我登陆index.ejs文件并输入一个随机ID(例如1)时,它都会转到相应的URL并显示结果,我按下返回按钮并返回index.ejs并第二次尝试ID,此时服务器关闭并显示以下错误:

error: invalid input syntax for type integer: "NaN"
    at Parser.parseErrorMessage (c:\Users\user\Desktop\JS\RESTAPI\node_modules\pg-protocol\dist\parser.js:287:98)
    at Parser.handlePacket (c:\Users\user\Desktop\JS\RESTAPI\node_modules\pg-protocol\dist\parser.js:126:29)
    at Parser.parse (c:\Users\user\Desktop\JS\RESTAPI\node_modules\pg-protocol\dist\parser.js:39:38)
    at Socket.<anonymous> (c:\Users\user\Desktop\JS\RESTAPI\node_modules\pg-protocol\dist\index.js:11:42)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:324:12)
    at readableAddChunk (node:internal/streams/readable:297:9)
    at Readable.push (node:internal/streams/readable:234:10)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
  length: 141,
  severity: 'ERROR',
  code: '22P02',
  detail: undefined,
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: "unnamed portal parameter $1 = '...'",
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'numutils.c',
  line: '235',
  routine: 'pg_strtoint32'
}

Node.js v18.16.0

下面是exercises.ejs文件以供进一步参考:

<!-- exercises.ejs -->

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="styles.css">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
  <title>FITNESS TRACKER API - Userfit</title>
</head>
<body style="background-color: #222222; color: white;">
  <h1 class="text-center">Fitness Tracker - Userfit</h1>
  <table class="table table-dark">
    <thead>
      <tr>
        <th scope="col">Exercises ID</th>
        <th scope="col">Name</th>
        <th scope="col">Description</th>
        <th scope="col">Category</th>
        <th scope="col">Calories Burned</th>
      </tr>
    </thead>
    <tbody>
      <% exercises.forEach((exercise) => { %>
        <tr>
          <td><%= exercise.exercise_id %></td>
          <td><%= exercise.exercise_name %></td>
          <td><%= exercise.exercise_description %></td>
          <td><%= exercise.exercise_category %></td>
          <td><%= exercise.calories_burned_per_minute %></td>
        </tr>
      <% }); %>
    </tbody>
  </table>
  <button onclick="goBack()">Go Back</button>

<script>
function goBack() {
  window.history.back(); // This will take the user back to the previous page
}
</script>
</body>
</html>

它不仅在尝试通过ID获取练习时崩溃,甚至在我再次返回localhost:3000后进行简单刷新时也会崩溃。我不知道是什么问题,我试过使用人工智能,但是,它也不能为我提供任何可行的帮助。我还检查了它是否第二次转到适当的URL,它确实如此,我还看到它通过研究URL将适当的练习ID作为参数。我会很感激任何帮助来解决这个问题,我是一个新手nodejs,api的。

nr9pn0ug

nr9pn0ug1#

我在github https://github.com/brianc/node-postgres/issues/2310上发现了这个,错误是invalid input syntax for integer: "NaN"。似乎exercise_id不是一个有效的整数,
因此,您可能应该首先验证parseInt是否返回有效的整数,例如。Number.isInteger(exercise_id),并为parseInt添加基本参数
您还可以使用promise并使用thencatch来处理错误,以便找出错误发生的位置。

const getExerciseById = (req, res) => {
  const exercise_id = parseInt(req.params.exercise_id, 10);

  if (Number.isInteger(exercise_id)) {
    console.log('valid id', exercise_id);
    pool.query(queries.getExerciseById, [exercise_id])
      .then((results) => {
        res.render('exercises', { exercises: results.rows }
      })
      .catch((error) => {
        throw error;
      });
  } else {
    console.log('invalid id', exercise_id);
    /* send an error page if the id is not valid */
  }
};

希望这能帮上忙

相关问题