Jakub
Jakub

Reputation: 2709

How to check if an email is already taken in MongoDB

I'm building an API in NodeJS and MongoDB. The API in general just manages Students and Projects. I need to add a new route to check if an email already has been taken in the DB. As param I need to pass the email from the body as req.body.email and then check if it is available. I tried 2 ways but nothing worked for me and not really know how to fix it.

The route I did in as first:

router.get("/check-email", async (req, res) => {
    await Student.emailCheck(req.body.email, (error, student) => {
        if (error) {
            return next(error);
        }

        if (student) {
            res.status(401).json({ error: "Email already used" });
        } else {
            res.json({ message: "Email is available" });
        }
    });
});

and model:

const mongoose = require("../utilities/dbConnect");
require("mongoose-type-email");

const schema = {
    name: {
        type: String,
        required: true
    },
    surname: {
        type: String,
        required: true
    },
    email: {
        type: mongoose.SchemaTypes.Email,
        required: true,
        unique: true
    },
    dateOfBirth: {
        type: String,
        required: true
    }
};

const collectionName = "student";
const studentSchema = mongoose.Schema(schema);
const Student = mongoose.model(collectionName, studentSchema);

const emailCheck = (email, cb) => {
    Student.findOne({ email: email }).exec((error, student) => {
        if (error) {
            return cb(error);
        }
        cb(null, student);
    });
};

module.exports = { Student, emailCheck };

Method 2 route:

await validateEmailAccessibility(req.body.email).then(
           valid => {
            if (valid) {
                res.send("Email is valid");
              } else {
                res.send("Email already used");
              }
           }
       );

and using a utility

let Student = require("../models/student.model");

const validateEmailAccessibility = async email => {
    const result = await Student.findOne({ email: email });
    return result !== null;
};

module.exports = validateEmailAccessibility;

I would like to understand the best way to achieve my goal and what I'm doing wrong in my ways.

Upvotes: 0

Views: 739

Answers (1)

Valijon
Valijon

Reputation: 13103

The problem is on data type.

In your scheme definition, email field is typeof mongoose.SchemaTypes.Email. But, when you are searching inside Mongo, you pass String type.

EDIT:

Working code (used app instead of Route):

app.post("/check-email", function (req, res) {
    Student.findOne({ email: req.body.email }, (error, result) => {

        if (result) {
            res.status(401).json({ error: "Email already used" });
        } else {
            res.json({ message: "Email is available" });
        }
    });
});

Upvotes: 1

Related Questions