TypeError: undefined is not a function in nodejs

匿名 (未验证) 提交于 2019-12-03 08:46:08

问题:

This is my users.js model.

var mongoose = require('mongoose')   , crypto = require('crypto')   , mongoTypes = require('mongoose-types');  mongoTypes.loadTypes(mongoose, 'email'); mongoose.connect('mongodb://localhost/popbroker');  function hash1 (msg, key) {    return crypto.createHmac('sha256', key).update(msg).digest('hex'); };  function required(val) { return val && val.length; }  var Schema = mongoose.Schema   , ObjectId = Schema.ObjectId;  var UserSchema = new Schema({     username: {       type: String,       validate: [required,"Username is required"],       index: {unique: true}     },     email: {         type: mongoose.SchemaTypes.Email,         validate: [required, 'Email required'],         index: { unique: true }     },     password: {         type: String,         validate: [required, 'Password required'],     },     socialauth:{       type:String,      createdAt: {         type: Date,         'default': Date.now     } });   var UserApiSchema = new Schema({     user :ObjectId,     apiKey: {         type: String,         validate: [required, 'Senha é obrigatório'],     },     createdAt: {         type: Date,         'default': Date.now     } });   UserSchema.path('email').validate(function (v, fn) {     User.count({email: v}, function (err, val) {         if (err) fn(false);         fn(val==0);     }); }, 'Email exists!');   UserSchema.path('username').validate(function(v,fn){   User.count({username:v},function(err,val){     if(err) fn(false);     fn(val==0);   }); },'Username exists');  UserApiSchema.path('apiKey').validate(function(v,fn){   UserApi.count({apiKey:v},function(err,val){     if(err) fn(false);     fn(val == 0);   }); }, 'Api Key wrong');   UserSchema.statics.authenticate = function (email, password, fn) {     this.findOne({email: email}, function (err, user) {         if (!user) return fn(new Error('cannot find user'));         if (user.password == hash1(password, conf.secret)) return fn(null, user);         // Otherwise password is invalid         fn(new Error('invalid password'));     }) ;};  UserApiSchema.statics.createApi = function(user,fn){   var instance = new UserApi();   instance.user = user;   instance.apiKey = "asdasdacas121213dasasd";   console.log("username is " + user.username);   instance.save(function(err){     fn(err,instance);    }); };   UserSchema.statics.getUser = function(userid){   var user = mongoose.model('User', UserSchema);   var query = user.findOne({'_id':userid})   query.exec(function (err, user) {   if (err) return handleError(err);   console.log(user.username);   return user; }); }   UserApiSchema.statics.getUser = function(apiKey,fn){   var usAp = UserApiSchema   var userApi = mongoose.model('UserApi', UserApiSchema);   var user = mongoose.model('User', UserSchema);   var query = userApi.findOne({ 'apiKey': apiKey });     query.exec(function (err, userApi) {   if (err) return handleError(err);   console.log(userApi.user);   user = user.getUser(userApi.user);   fn(err, userApi);;// Space Ghost is a talk show host. }); };  UserSchema.statics.newUser = function (email, password,username, fn) {     var instance = new User();     var apiInstance = new UserApi();     instance.email = email;     instance.password = require('crypto').createHash('sha256').update(password).update('salt').digest('hex');     instance.username = username;      instance.save(function (err) {         fn(err, instance);     }); };  UserSchema.statics.resetPassword = function(userId, callback) {     var newPassword = '';     newPassword = newPassword.randomString(6);     var cripto = password;     var data = {}          data.password = crypto;      this.update({_id: userId}         , {$set: data}         , {multi:false,safe:true}         , function( error, docs ) {             if (error) {                 callback(error);             }             else {                 callback(null, newPassword);             }         }); }   var LinkSchema = new Schema({    user: ObjectId,    text: {       type: String,       validate: [required,"Text is required"],       index: {unique: true}     },     body: {         type: String,         validate: [required, 'Body is required'],         index: { unique: true }     },     createdAt: {         type: Date,         'default': Date.now     } })  /* Exporting findByid function to return back a link based on an id. */  LinkSchema.statics.newLink = function (text, body,user, fn) {     var instance = new Link();     instance.text = text;     instance.body =body;     instance.user = user;      instance.save(function (err) {         fn(err, instance);     }); };   /* Export findAll function to return back all the links.  */  exports.findAll = function(req,res){   console.log("Retrieving all the links");   db.collection('links',function(err,collection){     collecction.find().toArray(function(err,items){       res.send(items);      });   }); };    Link = mongoose.model('Link', LinkSchema);  exports.Link = Link;   User = mongoose.model('User', UserSchema); UserApi = mongoose.model('UserApi',UserApiSchema); exports.UserApi = UserApi; exports.User = User; 

As I'm new to nodejs, it is very difficult to understand what this error means or why it happens. Thus, what does the error mean and how to get rid of it?

Edit: This is my newUser call.

app.post(         '/signup/',         function(req, res) {              {console.log(req.body.username);                 User.newUser(                      req.body.email, req.body.password,req.body.username,req.body.apiKey,"pocket",                     function (err, user) {                         if ((user)&&(!err)) {                             console.log(user.username)                              UserApi.createApi(                                     user,function(err,userapi){                                         if((!err)){                                             console.log("Api created");                                             res.send("APi created");                                          }                                         else{                                             if(err.errors.apiKey){                                                 res.send(err);                                             }                                         }                                       });                             req.session.regenerate(function(){                                 req.session.user = user._id;                                 //res.send("Success here!");                               });                         } else {                             if (err.errors.email) {                               res.send(err)                                console.log(req.body.password);                               console.log(req.body.email);                               console.log(req.body);                             }                                                       if (err.errors.username) {                               res.send(err)                                console.log(req.body.password);                               console.log(req.body.email);                               console.log(req.body);                             }                            }                     });               }          }); 

回答1:

With your edit, the issue that you're passing more arguments than newUser is expecting. This results in fn being set the value of req.body.apiKey, which is apparently undefined:

UserSchema.statics.newUser = function (email, password, username, fn) {     // ... });  User.newUser(               // set to...     req.body.email,         // => email     req.body.password,      // => password     req.body.username,      // => username     req.body.apiKey,        // => fn     "pocket",               // => (unnamed), arguments[4]     function(err, user) {   // => (unnamed), arguments[5]         // ...     } }); 

You'll either want to edit the function to name the additional arguments or remove them from the call if they're not actually necessary (since you're creating a UserApi instance both inside newUser and within the intended callback).


[originally]

The error means you're attempting to call a value of undefined.

One possibility is the fn argument as newUser will attempt to call it whether it's actually a function or not:

UserSchema.statics.newUser = function (email, password,username, fn) {     //...         fn(err, instance);     //... }); 

But, the value of fn depends on how you call newUser:

// fn = undefined User.newUser('email@domain', 'password', 'username');  // fn = function User.newUser('email@domain', 'pass', 'user', function (err, user) { }); 

So, you'll either want to test that fn is a function before attempting to call it:

instance.save(function (err) {     if (typeof fn === 'function') {         fn(err, instance);     } }); 

Or you can pass fn directly to Model#save, which already handles when fn is undefined:

instance.save(fn); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!