Grateful
Grateful

Reputation: 10185

How to to access first and last name for the following user model (based on mongoose)?

I am looking at some code, with a user schema, similar to the following.

var UserSchema = new mongoose.Schema(
   {
        email: {
            type: String,
            lowercase: true,
            unique: true,
            required: true
        },

        password: {
            type: String,
            required: true
        },

        profile: {
            firstName: {
                type: String
            },
            lastName: {
                type: String
            }
        }
    }
);

Now, as far as I can understand, the top-level properties are email, password and profile.... firstName and lastName should only be accessible from within profile. However, the details are being accessed with something like the following.

exports.register = function(req, res, next) { 

  // Check for registration errors
  const email = req.body.email;
  const password = req.body.password;
  const firstName = req.body.firstName;
  const lastName = req.body.lastName;

  // Return error if no email provided
  if (!email) {
    return res.status(422).send({ error: 'You must enter an email address.'});
  }

  // Return error if no password provided
  if (!password) {
    return res.status(422).send({ error: 'You must enter a password.' });
  }

  // Return error if full name not provided
  if (!firstName || !lastName) {
    return res.status(422).send({ error: 'You must enter your full name.'});
  }

...

I don't seem to understand why the firstName and lastName are being accessed directly with req.body.firstName instead of req.body.profile.firstName. There don't seem to be any virtual attributes in place either. So what's going on!?

Upvotes: 1

Views: 2034

Answers (3)

DanielKhan
DanielKhan

Reputation: 1208

In an express application request parameters are passed in as first parameter of a route (req, res, next). The sample code posted shows the result of a POST request to a route called /register. This data does not relate to the model posted with the question.

To be able to work with the model, the data needs to be stored into a new Mongoose object. So within the route one would write:

exports.register = function(req, res, next) { 
    const User = new User();
    User.profile.firstName = req.body.firstName;
    // ... and so on
    User.save((err, savedUser) => { 
        if(err) return next(err);
        // end request
    });
}

Please note that some kind of sanity check is recommended when dealing with user provided variables. Using it like in my example above may enable an attacker to store a string of arbitrary length inside the database which is most probably not desired.

Upvotes: 1

Arif Khan
Arif Khan

Reputation: 5069

req.body added by body-parser and this is not related to your mongoose model. You will get data in req.body sent from front-end(client side). Apart from this issue, I would like to recommend you to use following format that may help you

You may like to use schema for sub-document

var profileSchema = new Schema({
   firstName: String,
   lastName: String
});

var UserSchema = new mongoose.Schema({
    email: {
        type: String,
        lowercase: true,
        unique: true,
        required: true
    },

    password: {
        type: String,
        required: true
    },

    profile: profileSchema
});

and may use like

exports.register = function(req, res, next) { 

  if(!req.body)
      return res.status(500).send({ error: 'Unable to parse data'});

  // Check for registration errors
  const userData = {
    email: req.body.email,
    password: req.body.password,
    profile: {
      firstName: req.body.firstName,
      lastName: req.body.lastName
    }
  }

  // Return error if no email provided
  if (!userData.email) {
    return res.status(422).send({ error: 'You must enter an email address.'});
  }

  // Return error if no password provided
  if (!userData.password) {
    return res.status(422).send({ error: 'You must enter a password.' });
  }

  // Return error if full name not provided
  if (!userData.profile.firstName || !userData.profile.lastName) {
    return res.status(422).send({ error: 'You must enter your full name.'});
  }

  var newUser = new User(userData);// you must import user schema before using User

Upvotes: 2

Grateful
Grateful

Reputation: 10185

As pointed out by @DanielKhan, within the above comments, mongoose is only being used to model the data. However, at this point, it has nothing to do with the data coming in directly from the client. Hence, all the fields, including email, password, and first name, and last name will be retrieved at the same level... using req.body.

Upvotes: 1

Related Questions