I keep getting the same error "User is not a function" when I call my API method.
Has anybody got an ideas why this might be.
Api method:
//need to export the api methods.
var User = require('../models/user');
var passport = require('passport');
module.exports.create = function(req, res) {
//TODO: error checking.
var user = new User();
console.log(req);
user.firstName = req.body.firstName;
user.secondName = req.body.secondName;
user.email = req.body.email;
user.setPassword(req.body.password);
user.save(function(err) {
res.status(200);
});
};
user model:
var mongoose = require('mongoose');
var crypto = require('crypto');
var userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true
},
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
hash: String,
salt: String
});
userSchema.methods.setPassword = function(password){
};
userSchema.methods.validPassword = function(password) {
};
mongoose.model('User', userSchema);
Let me know if I need to enter any more files.
Thanks
You need to export the mongoose model you created at the end of the User Model file. Something like
module.exports = mongoose.model('User', userSchema);
Related
Trying to code the backend, and this throws an error in the console. What could be the problem? I imported user.js as a requirement, but still does not work.
Error: mongoose.Error.MissingSchemaError(name); Schema hasn't been registered for model "User". Use mongoose.model(name, schema)
Passport.js
const passport = require('passport');
const user = require('../schema/user');
const LocalStrategy = require('passport-local').Strategy;
const mongoose = require('mongoose');
const User = mongoose.model('User');
passport.use(new LocalStrategy({
usernameField: 'email'
},
(username, password, done) => {
User.findOne({ email: username }, (err, user) => {
if (err) { return done(err); }
if (!user) {
return done(null, false, {
message: 'Incorrect username.'
});
}
if (!user.validPassword(password)) {
return done(null, false, {
message: 'Incorrect password.'
});
}
return done(null, user);
});
}
));
User.js
const mongoose = require("mongoose");
const crypto = require('crypto');
const jwt = require('jsonwebtoken');
const userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true
},
name: {
type: String,
required: true
},
hash: String,
salt: String
});
userSchema.methods.setPassword = function (password) {
this.salt = crypto.randomBytes(16).toString('hex');
this.hash = crypto
.pbkdf2Sync(password, this.salt, 1000, 64, 'sha512')
.toString('hex');
};
userSchema.methods.validPassword = function (password) {
const hash = crypto
.pbkdf2Sync(password, this.salt, 1000, 64, 'sha512')
.toString('hex');
return this.hash === hash;
};
userSchema.methods.generateJwt = function () {
const expiry = new Date();
expiry.setDate(expiry.getDate() + 7);
return jwt.sign({
_id: this._id,
email: this.email,
name: this.name,
exp: parseInt(expiry.getTime() / 1000, 10),
}, process.env.JWT_SECRET );
};
module.exports = mongoose.model('User', userSchema);
in passport.js file, you don't need to require require('mongoose') and mongoose.model('User'), so delete them and change user to User like this:
const passport = require('passport');
const User = require('../schema/user');// change user to User
const LocalStrategy = require('passport-local').Strategy;
Error : usr.findOneAndUpdate is not a function
Model:
var mongoose = require('mongoose')
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt')
var schema = new Schema({
email: { type: String, require: true },
username: { type: String, require: true },
password: { type: String, require: true },
creation_dt: { type: String, require: true },
tasks:[{type:{type:String}}]
});
module.exports = mongoose.model('User',schema)
i want to Add some Task in tasks array so i use post method for That and code is
Code:
router.post('/newTask', function (req, res, next) {
var dataa = {
pName: req.body.pName,
pTitle: req.body.pTitle,
pStartTime: req.body.pStartTime,
pEndTime: req.body.pEndTime,
pSessionTime: req.body.pSessionTime
}
var usr = new User(req.user)
usr.findOneAndUpdate(
{_id:req.user._id},
{$push:{tasks:dataa}}
)
try {
doc = usr.save();
return res.status(201).json(doc);
}
catch (err) {
return res.status(501).json(err);
}
})
i also read the documentation of findOneAndUpdate but i din't get solution please someone can Help out of this error....
Thank You.
You need to import your model into the file containing your routes. All mongoose methods are based off the schema that you define, not new instances you create.
For example, if you have a User model that looks like this:
// file is named user.js
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema ({
username: String,
password: String
})
module.exports = mongoose.model("User", userSchema)
You need to import the model so mongoose recognizes it as one
Like so (assuming the routes file and user model file are in the same directory):
const User = require("./user")
router.post("/newTask", (req, res) => {
User.findOneAndUpdate(//whatever you want to be updated)
})
There is a array of user IDs in currentUser.follow. Each user has posts with referenceId of PostSchema . Now I want to populate each user's post and store it in an array[userArray]. But due to scope issue the array remains empty. Please show me how I can get all the users with their post in the Array[userArray]
app.js
app.get("/", isLoggedIn, function(req, res){
var currentUser =req.user;
var userArray=[];
for(let fol of currentUser.follow){
User.findById(fol).populate("posts").exec(function(err, user){
if(err){
console.log(err);
}else{
console.log(user); // a user with populated posts
userArray.push(user);
console.log(userArray); //stores user but posts is not populated
}
});
}
console.log(userArray); // empty array
});
User Schema
var mongoose =require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var UserSchema = new mongoose.Schema({
name: String,
email: String,
username: String,
password: String,
posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Post"
}
],
follow: [String]
});
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", UserSchema);
Post Schema
var mongoose =require("mongoose");
var PostSchema = new mongoose.Schema({
text: String,
image: String,
author:{
id:{
type: mongoose.Schema.Types.ObjectId,
ref : "User"
},
username: String
},
createdAt: {type:Date, default:Date.now}
});
module.exports= mongoose.model("Post", PostSchema);
Because User.findById is asynchronous so the second console.log(userArray); will excute before the result pushed to userArray.
There is a better way to do this with $in operator and async/await:
app.get("/", isLoggedIn, async function(req, res){
try {
var currentUser = req.user;
var userArray = await User.find({_id: {$in: currentUser.follow}}).populate("posts");
console.log(userArray);
} catch(err) {
console.log(err);
}
});
Am creating a registration form where user needs to enter details of his emailid(username),password,DOB,Address,phoneno. All fields are mandatory here emailid acts as an username. I have designed my Mongoose Schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var User = new Schema({
username: String,
password: String,
phoneno: {
type: Number,
unique: true,
required: true
},
Address : {
type: String,
required: true
},
Dob: {
type: String,
required: true
}
},{
timestamps: true
});
User.plugin(passportLocalMongoose);
module.exports = mongoose.model('User', User);
My user router is given below
var express = require('express');
var UserDetails = express.Router();
var userSchema=require('../models/user');
var passport = require('passport');
const mongoose = require('mongoose');
var Verify = require('./verify');
UserDetails.post('/register', function(req, res, next) {
var newUser = new userSchema({
username : req.body.email,
Dob : req.body.dob,
Address : req.body.address,
phoneno : req.body.phoneno
});
userSchema.register(newUser,req.body.password, function(err, user) {
if (err) {
console.log(err);
return res.status(500).json({err: err});
}
passport.authenticate('local')(req, res, function () {
console.log(req);
console.log(res);
return res.status(200).json({status: 'Registration Successful!'});
});
});
});
This is the json object am sending via PostMan
{"email":"kannaa.in","password": "abcdef","phoneno":96930,"address":"396 SM Road","dob":"14-05-1992"}
But in the console and postman it says bad request if i try to perform the operation.However it stores the value in DB. I couldn't find out the error.
So after no one answered i found out myself what is the error about PassportJS expects the request to contain req.body.username it doesn't matter how many other datas you send it needs req.body.username from the request side. So all i had to change was rather than email i set it as username in postman and it worked like charm.
My postman Data
{"username":"kannaa.in","password": "abcdef","phoneno":96930,"address":"396 SM Road","dob":"14-05-1992"}
Here you can see my API controller method:
//need to export the api methods.
var mongoose = require('mongoose');
var User = require('../models/user');
var crypto = require('crypto');
module.exports.create = function(req, res) {
//TODO: error checking.
var user = new User();
user.firstName = req.body.firstName;
user.lastName = req.body.secondName;
user.email = req.body.email;
user.salt = crypto.randomBytes(16).toString('hex');
user.password = crypto.pbkdf2Sync(req.body.password, user.salt, 1000, 64).toString('hex');
//console.log(user);
user.save(function(err) {
res.status(200);
});
};
Here is my model:
var mongoose = require('mongoose');
var crypto = require('crypto');
module.exports = mongoose.model('User', {
email: {
type: String,
unique: true,
required: true
},
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
hash: String,
salt: String
});
Strangely enough even though my req.body contains all the information that I am trying to set, when I log the user at the end the only things that seem to be getting set are the first name and the salt?
Does anyone know why this is? And could you show me the correct way to do it?
Thanks