user.findOne не является функцией - PullRequest
0 голосов
/ 26 апреля 2020

Я учусь использовать паспорт js в своем приложении формы, и я использую объект пользователя в приложении, которое использует эту модель для сохранения пользователя в базе данных, но когда я возвращаю созданный объект пользователя и пытаюсь обновите этот объект с помощью метода findOne, с которым я сталкиваюсь user.findOne is not a function error Вот мой код.

Заранее спасибо за помощь.

user.js выглядит примерно так

var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");

var usersSchema = new mongoose.Schema({
    username:String,
    password:String,
    email:String
});

usersSchema.plugin(passportLocalMongoose);

module.exports = mongoose.model("User",usersSchema);

Моя signup страница выглядит так

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <link href="https://fonts.googleapis.com/css2?family=Mitr:wght@500&display=swap" rel="stylesheet">
    <link rel="stylesheet" type="text/css" href="css/biodata.css">
</head>
<body>

  <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
        <a class="navbar-brand justify-content-around" id="navbar-home" href="/">Home</a>
        <div class="ml-auto" id="navbar-joint">
          <a class="navbar-brand" href="/signup">Sign Up</a>
          <a class="navbar-brand" href="/logout">Logout</a>
       </div>
  </nav>

<div class="card" id="signup-card">
  <div class="card-body" id="signup-card-body">
   <form action="/register" method="POST">
    <h3 class="d-flex justify-content-center">SIGN UP</h3>
  <div class="form-group">
       <input type="text" class="form-control form-control-lg" id="username" name="username" placeholder="Username">
    </div>
    <div class="form-group">
      <input type="email" class="form-control" id="email" name="email" placeholder="Email">
     </div>
  <div class="form-group">
    <input type="password" class="form-control form-control-lg" id="inputPassword" name="inputPassword" placeholder="Password">
  </div>
  <div class="form-group">
    <input type="password" class="form-control form-control-lg" id="confirminputPassword" name="confirminputPassword" placeholder="Confirm Password">
  </div>
  <div class="form-check">
    <input type="checkbox" class="form-check-input" id="exampleCheck1" name="exampleCheck1">
    <label class="form-check-label" for="exampleCheck1">I agree</label>
  </div>
  <div class="form-group">
     <button type="submit" class="btn btn-primary btn-lg btn-block">Submit</button>
  </div>
</form>

  </div>
</div>



<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>

Моя app.js выглядит следующим образом

var express = require("express");
var app = express();
var mongoose = require("mongoose");
var passport = require("passport"),
    localStrategy = require("passport-local");
const User = require("./models/User");
var expressSession = require("express-session");


mongoose.connect('mongodb://localhost/users', {useNewUrlParser: true, useUnifiedTopology: true}).catch(function(reason){
    console.log('Unable to connect to the mongodb instance. Error: ', reason);
});

app.set('view engine', 'ejs');
var bod = require("body-parser");
app.use(bod.urlencoded({extended:true}));
app.use(passport.initialize());
app.use(passport.session());
app.use(expressSession({
    secret:"the key",
    resave:false,
    saveUninitialized:false
}));

passport.use(new localStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

app.use(express.static(__dirname + '/resources'));

/*
var usersSchema = new mongoose.Schema({
    username:String,
    password:String,
    email:String
});

var user = mongoose.model("User",usersSchema);

*/
app.get("/", function(req, res) {
    res.render("home");
});
app.get("/home", function(req, res) {
    res.render("home");
});

//problem method
app.post("/register",function(req,res){
    var userName = req.body.username;
    var inputPassword = req.body.inputPassword;
    var email = req.body.email;
    var exampleCheck1 = req.body.exampleCheck1;
    var confirminputPassword = req.body.confirminputPassword;

    if(exampleCheck1==="on"){
        if(inputPassword===confirminputPassword){

            User.register( new User({username:userName}),inputPassword, function(err,user){
                console.log(user); 
               // here I tried to cast the returned object into User.js object but it didn't work
              //  user = new User();
                if(err){
                    console.log(err);
                   return res.render("signup");
                }
                 //I am trying to update returned object with email, I am not sure if this is the correct way to do it, would welcome suggestions. but at this point the user.findOne is not a function error is thrown. 
                 user.findOne({username:userName},function(err,user){
                         user.email = email;
                        user.save();
                         console.log(user);

                     });
                passport.authenticate("local")(req,res,function(){

                    res.render("bioform",{userName:userName});

                });
            });


        }else{
            console.log("Passwords doesn't match!!!");
            res.render("signup");
        }

    }else{
        console.log("Agree to Terms!!!");
        res.render("signup");
    }


});


//


app.get("/signup", function(req, res) {
    res.render("signup");
});

app.listen(3000,function(){
    console.log("Server started");
});

1 Ответ

1 голос
/ 26 апреля 2020

Вы пытаетесь вызвать findOne в объекте, возвращаемом вызовом register из passport-local-moongoose.

Вместо этого вам следует вызывать его через User модель:

const User = require("./models/User");
[...]

User.register(new User({ username: userName }), inputPassword, function(err, user) {
    [...]

    // Use User model instead of the object returned in User.register.
    User.findOne({ username: userName }, function(err, user) {
        // Your logic here.
    });
});
...