Search code examples
node.jsrestapixmlhttprequest

Why can't Restful pass body into database


I'm creating a RESTful API.

I wanna use GET method to check if lastName exists. If it can find lastName, return "YES", otherwise, call a POST method to create a data with lastName entered.

The problem is that it can create a new data, but the body is empty. Ideally, it should contain a value with lastName, like "lastName": "James",

{
  "_id": "58a22c3c3f07b1fc455333a5",
  "__v": 0
}

Here is my code.

router.route("/findLastName/:id")
    .get(function(req,res){
        var response;
        mongoOp.findOne({deviceID: req.params.id}, function(err, result){
          if (err) { 
            response = {"error" : true,"message" : "Error fetching data"};
            res.json(response);
          }
          if (result) {
            response = "YES";
            res.send(response);
          } else {
            var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
            var xhr = new XMLHttpRequest();
            var POSTurl = "http://localhost:6002/users";
            var params = "lastName=" + req.params.id;

            xhr.open("POST", POSTurl, true);
            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            xhr.send(params);
          }
        });
      })

PS: GET method works well, not a issue.


Solution

  • Let me modify a bit of your code and add comments as pointers:

    // changed findLastName to find-last-name. It's a common convention,
    // urls need to be case insensitive. It doesn't concern lastName, as
    // that's a parameter, internal to your app so it's fine.
    // even better if you name the route `find-or-create` or something, to better
    // reflect what you're doing.
    router.route("/find-last-name/:lastName")
    .get(function(req,res){
        var response;
        mongoOp.findOne({deviceID: req.params.lastName}, function(err, result){
          if (err) { 
            response = {"error" : true,"message" : "Error fetching data"};
            // Adding a `return statement here. If you don't return, you'll tell 
            // the user that there was an error, but your code continues running
            // potentially calling that res.json twice.
            // Also, since it's an internal error, it's common to tell the client
            // about it, by setting the status to 500
            return res.status(500).json(response);
          }
          if (result) {
            // turning the message to JSON instead. You started that above,
            // and for the sake of your clients (your frontend), it's 
            // better to stick to JSON. Also you can pass useful info, such as
            // _id of the document.
    
            // Again adding a `return` here, and then the rest of the code
            // is nested one level less. not required, but some people like that.
            response = {
              message: "Last name exists."
            };
            return res.json(response);
          }
          // Here begins the new code. I'm typing what I can infer from your code,
          // I don't know if your MongoDB driver looks like that exactly.
          mongoOp.insert({ 
            deviceId: req.params.lastName
            // add other optional properties here.
          }, function (err, response) {
            if (err) {
              var message = {
                error: true,
                message: 'Cannot save new entry.'
              }
              return res.status(500).json(message);
            }
            // if we're here, everything went ok. You can probably return
            // the _id of the given user.
            return res.json({
              message: 'New user created.',
              _id: response._id
            });
          });
        });
      })