我的API的删除部分有什么问题?

时间:2019-11-19 05:03:41

标签: node.js mongodb rest vue.js mongoose

我正在上一个Web编程课程,我们正在编写Web服务器API。我目前已经实现了POST和GET,但是在实现DELETE时遇到了一些麻烦。我在这里做错了什么?对于我正在做的事情的透彻解释,我将不胜感激,因为我实际上是在尝试学习该材料(除非它当然只是格式化错误)。

还有很多尚未实现的部分,所以我确定有很多错误。通常,我关心的是DELETE,以及我的代码中我不理解的任何其他东西。

我已将域名替换为fakeDomainName.com

index.html和script.js在公共文件夹中。我的主目录中的start.js。

我们正在使用Node.js服务器和MongoDB数据库存储信息来创建一个简单的投票类型api进行练习。当前,POST和GET可以按预期工作,但是DELETE给了我这些错误:

spread.js:25 DELETE http://fakeDomainName.com:3010/api/candidates/undefined 500 (Internal Server Error)
(anonymous) @ spread.js:25
e.exports @ spread.js:25
e.exports @ spread.js:25
Promise.then (async)
r.request @ spread.js:25
r.<computed> @ spread.js:25
(anonymous) @ axios.min.js:477
deleteItem @ script.js:65
invokeWithErrorHandling @ vue.js:1855
invoker @ vue.js:2173
original._wrapper @ vue.js:7416

spread.js:25 Uncaught (in promise) Error: Request failed with status code 500
    at e.exports (spread.js:25)
    at e.exports (spread.js:25)
    at XMLHttpRequest.d.onreadystatechange (spread.js:25)
e.exports @ spread.js:25
e.exports @ spread.js:25
d.onreadystatechange @ spread.js:25
XMLHttpRequest.send (async)
(anonymous) @ spread.js:25
e.exports @ spread.js:25
e.exports @ spread.js:25
Promise.then (async)
r.request @ spread.js:25
r.<computed> @ spread.js:25
(anonymous) @ axios.min.js:477
deleteItem @ script.js:65
invokeWithErrorHandling @ vue.js:1855
invoker @ vue.js:2173
original._wrapper @ vue.js:7416

这是我在“ start.js”中的代码,这是我用来启动服务器的代码。

const express = require('express');
const bodyParser = require("body-parser");

const multer = require('multer');
const upload = multer({
  dest: './public/images/',
  limits: {
    fileSize: 10000000
  }
});

const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: false
}));

app.use(express.static('public'));

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/voting', {
  useNewUrlParser: true
});

var candidateSchema = new mongoose.Schema({
  name: String,
  bio: String,
  numVotes: String,
});

var Candidate = mongoose.model('Candidate', candidateSchema);

//add a candidate to the list
    app.post('/api/candidates', async(req, res) => {
      console.log("initiated post request");
      const candidate = new Candidate({
        name: req.body.name,
        bio: req.body.bio,
        numVotes: req.body.numVotes,
      });
      this.addItem = candidate.data;
      try {
        await candidate.save();
      }
      catch (error) {
        console.log(error);
        res.sendStatus(500);
      }
    });

    // Get a list of all of the candidates.
    app.get('/api/candidates', async(req, res) => {
      console.log("initiated get request");
      try {
        let candidate = await Candidate.find();
        res.send(candidate);
      }
      catch (error) {
        console.log(error);
        res.sendStatus(500);
      }
    });

    //delete a candidate from the list
    app.delete('/api/candidates/:id', async(req, res) => {
      console.log("initiated delete request");
      Candidate.deleteOne({ _id: req.params.id }, function(err) {
        if (err) res.sendStatus(500);
        else {
          console.log(req.params.id, "deleted successfully");
          res.sendStatus(200);
        }
      });
    });

    //edit a candidate
    app.put('/api/candidates/:id', async(req, res) => {
      console.log("initiated put(edit) request");
      try {
        let candidate = await Candidate.findOne({ _id: req.params.id });
        candidate.name = req.body.name;
        candidate.bio = req.body.bio;
        candidate.numVotes = req.body.numVotes;
        candidate.save();
        res.sendStatus(200);
      }
      catch (error) {
        console.log(error);
        res.sendStatus(500);
      }
    });

    app.listen(3010, () => console.log('Server listening on port 3010!'));

这是我在script.js中的代码,该代码链接到我的index.html页面:

    var app = new Vue({
      el: '#app',
      data: {
        name: "",
        bio: "",
        numVotes: "",
        file: null,
        addItem: null,
        items: [],
        findName: "",
        findItem: null,
      },
      created() {
          this.getItems();
        },

      computed: {
        suggestions() {
          return this.items.filter(item => item.title.toLowerCase().startsWith(this.findTitle.toLowerCase()));
        }
      },

      methods: {

        async postItem(item) {
            console.log("initiated");
          try {
            let response = await axios.post('/api/candidates', {
              name: this.name,
              bio: this.bio,
              numVotes: this.numVotes,
            });
            this.addItem = response.data;
          }
          catch (error) {
            console.log(error);
          }
        },

        async getItems() {
          try {
            let response = await axios.get("/api/candidates");
            this.items = response.data;
            return true;
          }
          catch (error) {
            console.log(error);
          }
        },

        selectItem(item) {
          this.findName = "";
          this.findItem = item;
        },


        async deleteItem(item) {
          try {
            let response = axios.delete("/api/candidates/" + item._id);
            this.findItem = null;
            this.getItems();
            return true;
          } catch (error) {
            console.log(error);
          }
        },

        async editItem(item) {
          try {
            let response = await axios.put("/api/candidates/" + item._id, {
              name: this.findItem.name,
              bio: this.findItem.bio,
              numVotes: this.findItem.numVotes,
            });
            this.findItem = null;
            this.getItems();
            return true;
          } catch (error) {
            console.log(error);
          }
        },
      },

    });

最后,这是我在index.html中使用的代码:

<!DOCTYPE HTML>
<html>

<head>
    <title></title>

</head>

<body>

    <h2>Hello World</h2>

    <div id="app">
        <div>
            <div>
                <input v-model="name" placeholder="Name">
                <p></p>
                <input v-model="bio" placeholder="Bio">
                <p></p>
                <input v-model="numVotes" placeholder="Number of votes">
                <button @click="postItem">Upload</button>
                <button @click="deleteItem">Delete</button>

            </div>
            <div v-if="addItem">
                <h2>{{addItem.name}}</h2>
                <h2>{{addItem.bio}}</h2>
                <h2>{{addItem.NumVotes}}</h2>
            </div>
        </div>

        <h2>Candidates:</h2>
        <div v-for="item in items">
            <div @click="selectItem">
            <h2>Name: {{item.name}}</h2>
            <h2>Bio: {{item.bio}}</h2>
            <h2>Number of Votes: {{item.numVotes}}</h2>
            </div>
        </div>
    </div>

    <!--Vue and axios-->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.2/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="/script.js"></script>

</body>

</html>

2 个答案:

答案 0 :(得分:0)

正如您在url中看到的那样,您没有获得参数id,其显示为未定义 //fakeDomainName.com:3010/api/candidates/undefined 由于它给了错误,如果您将id传递给它,它将同样有效

//delete a candidate from the list
    app.delete('/api/candidates/:id', async(req, res) => {
      console.log("initiated delete request");
      Candidate.findOneAndDelete({ _id: req.params.id }, function(err) {
        if (err) res.sendStatus(500);
        else {
          console.log(req.params.id, "deleted successfully");
          res.sendStatus(200);
        }
      });
    });```

答案 1 :(得分:0)

我用邮递员测试了您的节点。 “删除”很好。但是正如您在错误本身中看到的那样
DELETE http://fakeDomainName.com:3010/api/candidates/undefined参数item id的发送未定义,因此无法删除。

在您的POST请求中(在服务器/节点侧),您可以添加一个sendStatus(200)以避免挂起发布请求。此外,您可以获取已保存的id保存Candidate

的项目

像这样:

    app.post('/api/candidates', async(req, res) => {
  console.log("initiated post request");
  const candidate = new Candidate({
    name: req.body.name,
    bio: req.body.bio,
    numVotes: req.body.numVotes,
  });
  this.addItem = candidate.data;
  try {
      console.log("Await save...");
    let data = await candidate.save();
    console.log("Done");
    res.statusCode = 200;
    res.setHeader('content-type','application/json');
    res.end(JSON.stringify(data));
  }
  catch (error) {
    console.log(error);
    res.sendStatus(500);
  }
});

响应如下:

{
"_id": "5dd38cb16f47912b40a1deef",
"name": "Ken Adams",
"bio": "bio",
"numVotes": "10",
"__v": 0

}