0

I am trying to parse and save a name field into separate first and last names for a mongoose User model. My model schema looks like this:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = new Schema({
    username: {
        type: String,
        required: true
    },
    firstName: {
        type: String
    },
    lastName: {
        type: String
    },
    role: {
        type: String,
        default: 'Guest',
        enum: ['Organiser', 'Recipient', 'Contributor','Guest']
    }
})

UserSchema.methods = {

    saveParsedNames: function (nameString) {

        function parseName(str) {
            var nameArr = str.split(' ');
            var firstName = nameArr[0];
            var lastName = nameArr.slice(1,nameArr.length).join(' ').trim();
            var parsedNames = [firstName, lastName];
            return parsedNames;
        }

        var parsedNames = parseName(nameString);
        this.firstName = parsedNames[0];
        this.lastName = parsedNames[1];
        return this.save()

    }

}

module.exports = mongoose.model('User', UserSchema);

Right now, however, when I call user.saveParsedNames("some name string"), nothing is returned, and nothing gets written to the database. Nor does any error get thrown in the error block in the method. It's "undefined". It smells like some asynchronous problem, but I can't see where. Can anyone light the way here?

How can I update the User model with the new firstName and lastName properties, and return the updated object with saveParsedNames() method?

UPDATE

Here is the updated method, working as it is now not returning anything but can be called correctly by the callback. I've liberally used Neil Lunn's answer for a similar question to get the correct method here:

UserSchema.methods = {

    saveParsedNames: function (nameString, cb) {

        var model = this.model(this.constructor.modelName, this.schema);

        function parseName(str) {
            var nameArr = str.split(' ');
            var firstName = nameArr[0];
            var lastName = nameArr.slice(1,nameArr.length).join(' ').trim();
            var parsedNames = [firstName, lastName];
            return parsedNames;
        }

        var parsedNames = parseName(nameString);

        console.log(model);

        return model.findByIdAndUpdate(this._id, {
                firstName: parsedNames[0],
                lastName:parsedNames[1]
             },cb);
    }

}

And here is it being called:

createdUser.saveParsedNames(nameString, function (err, doc) {
                console.log(doc);
            });

Thanks to Neil Lunn for the answer on his other post https://stackoverflow.com/a/22495224/52092

Community
  • 1
  • 1
The Pied Pipes
  • 1,425
  • 2
  • 16
  • 29
  • @Neil Lunn I'm not getting how marking it as a duplicate actually helps me out. I've looked at those other questions, and still can't figure out how to make the method work, and have been closely reading the docs to take their example. – The Pied Pipes Mar 20 '15 at 22:07
  • You are trying to return a value from an asynchronous function. That is what the [duplicate question](http://stackoverflow.com/questions/6847697/how-to-return-value-from-an-asynchronous-callback-function) and it's answers explain you cannot do, and how to rather approach it. – Neil Lunn Mar 20 '15 at 22:36

0 Answers0