0

I'm learning MERN stack development and I'm making a practice app with user login/registration. I have the Node server and MongoDB up and running, and I'm able to register new users, update usernames & passwords, retrieve a list of users, and retrieve info about a single user. I'm doing this using post/get requests to localhost:4000/credentials-test/etc with Postman (I haven't actually connected the front end yet).

I'm able to get info on a single user with the following code in my server.js file:

credsRoutes.route('/user/:id').get(function(req, res) {
    let id = req.params.id;
    User.findById(id, function(err, user) {
        res.json(user);
    });
});

I figured I'd be able to do something similar to check if a username already exists (to prevent duplicate usernames on registration or username changing), with the following code:

credsRoutes.route('/check-user/:username').get(function(req, res) {
    let username = req.params.username;
    User.find(username, function(err, user) {
      if (!user)
        res.json('User not found :(');
      else
        res.json('User found! Details:');
        res.json(user);
    });
});

But the response from localhost:4000/credentials-test/check-username/testuser is always User not found :(, even when the username definitely belongs to an existing user.

Any ideas why this might be happening and how I can implement a working solution?

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
AJT
  • 216
  • 2
  • 6
  • 31
  • 1
    `User.findOne({ username },...` The `find()` returns an **array** and not a single object or `null` as you were expecting. Alternately `user.length != 0` works for arrays. See also [`findOne()`](https://mongoosejs.com/docs/api/model.html#model_Model.findOne) in the mongoose documentation. – Neil Lunn Oct 03 '19 at 09:37

1 Answers1

1

You need to pass a query object into the Mongoose model. Also, it's wise to return out of the function when you call res.json() because the rest of the function could still run, .end() is a method that will explicitly end the client's request.

try this:

credsRoutes.route("/check-username/:username").get(function(req, res) {
    const username = req.params.username;

    User.findOne({ username }, function(err, user) {
        if (!user) {
            return res.json("User not found :(").end();
        }

        return res.json(`User found! Details: ${user}`).end();
    });
});

`

Dan Starns
  • 3,765
  • 1
  • 10
  • 28
  • 1
    Thank you for your answer. Directly copying your code crashed my server when I sent the post request, which I think was down to a missing `return` before `res.json("User found! Details:");`, but using your code along with `findOne` I came up with this working solution: `credsRoutes.route('/check-username/:username').get(function(req, res) { const username = req.params.username; User.findOne({username: username}, function(err, user) { if (!user) { return res.json("User not found :(").end(); } return res.json(\`User found! Details: ${user}\`); }); });` – AJT Oct 03 '19 at 09:53
  • 1
    My bad, `Model.find()` will always return an array, `findOne` seems to be a better solution. ill change my snipped to relefect your changes & happy to hear you got it working. – Dan Starns Oct 03 '19 at 09:57