无法读取未定义的属性“用户名”

时间:2020-06-24 20:04:31

标签: javascript node.js mongodb express ejs

我一直在尝试向 / campgrounds 添加 用户关联 ,但突然出现此错误

Cannot read property 'username' of undefined
    at eval (C:\Users\karan\Desktop\YelpCamp\V9\views\campgrounds\show.ejs:20:44)
    at show (C:\Users\karan\Desktop\YelpCamp\V9\node_modules\ejs\lib\ejs.js:656:17)
    at tryHandleCache (C:\Users\karan\Desktop\YelpCamp\V9\node_modules\ejs\lib\ejs.js:254:36)
    at View.exports.renderFile [as engine] (C:\Users\karan\Desktop\YelpCamp\V9\node_modules\ejs\lib\ejs.js:459:10)
    at View.render (C:\Users\karan\Desktop\YelpCamp\V9\node_modules\express\lib\view.js:135:8)
    at tryRender (C:\Users\karan\Desktop\YelpCamp\V9\node_modules\express\lib\application.js:640:10)
    at Function.render (C:\Users\karan\Desktop\YelpCamp\V9\node_modules\express\lib\application.js:592:3)
    at ServerResponse.render (C:\Users\karan\Desktop\YelpCamp\V9\node_modules\express\lib\response.js:1012:7)
    at C:\Users\karan\Desktop\YelpCamp\V9\routes\campgrounds.js:53:21
    at C:\Users\karan\Desktop\YelpCamp\V9\node_modules\mongoose\lib\model.js:4883:16
    at C:\Users\karan\Desktop\YelpCamp\V9\node_modules\mongoose\lib\helpers\promiseOrCallback.js:24:16
    at C:\Users\karan\Desktop\YelpCamp\V9\node_modules\mongoose\lib\model.js:4906:21
    at C:\Users\karan\Desktop\YelpCamp\V9\node_modules\mongoose\lib\query.js:4390:11
    at C:\Users\karan\Desktop\YelpCamp\V9\node_modules\kareem\index.js:135:16
    at processTicksAndRejections (internal/process/task_queues.js:79:11)

这些是以下文件,我在其中将用户关联代码放在campground.js文件中的方法 router.post 中,并通过show.ejs文件显示用户名

请帮帮我

app.js

var express       = require("express"),
    app           = express(),
    bodyParser    = require("body-parser"),
    mongoose      = require("mongoose"),
    passport      = require('passport'),
    LocalStrategy = require('passport-local'),
    Campground    = require("./models/campground"),
    Comment       = require('./models/comment'),
    User          =require('./models/user.js'),
    seedDB        = require('./seeds');

    //Requiring Routes
var campgroundRoutes = require('./routes/campgrounds'),
    commentRoutes    = require('./routes/comments'),
    indexRoutes      = require('./routes/index');

// seedDB();   //Seed the database
    
app.use(bodyParser.urlencoded({extended: true}));
app.set("view engine", "ejs");
app.use(express.static(__dirname + "/public"))



//map global promise - to get rid of warning
mongoose.Promise =global.Promise;

//connect to mongoose
mongoose.connect("something",{
    useNewUrlParser: true,
    useUnifiedTopology: true
})
.then(() => console.log("MongoDB connected..."))
.catch(err => console.log(err))
     
//Passport Configuration 
app.use(require("express-session")({
    secret : "Once Again",
    resave : false,
    saveUninitialized : false
}))
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.use(function(req,res, next){
    res.locals.currentUser = req.user;
    next();
});

app.use('/', indexRoutes);
app.use('/campgrounds', campgroundRoutes);
app.use('/campgrounds/:id/comments', commentRoutes);



const port=3002;
app.listen(port, function(){
   console.log(`The YelpCamp Server is running on ${port}`);
});

campground.js

var express    = require('express');
var router     = express.Router();
var Campground = require('../models/campground')
    

    //INDEX - show all campgrounds
    router.get("/", function(req, res){
        // Get all campgrounds from DB
        Campground.find({}, function(err, allCampgrounds){
        if(err){
            console.log(err);
        } else {
            res.render("campgrounds/index",{campgrounds: allCampgrounds });
        }
        });
    });

    //CREATE - add new campground to DB
    router.post("/", isLoggedIn, function(req, res){
        // get data from form and add to campgrounds array
        var name = req.body.name;
        var image = req.body.image;
        var desc = req.body.description;
        var author = {
            id: req.user._id,
            username: req.user.username
        };
        var newCampground = {name: name, image: image, description: desc, author:author};
        // Create a new campground and save to DB
        Campground.create(newCampground, function(err, newlyCreated){
            if(err){
                console.log(err);
            } else {
                //redirect back to campgrounds page
                res.redirect("/campgrounds");
            }
        });
    });

    //NEW - show form to create new campground
    router.get("/new", isLoggedIn, function(req, res){
        res.render("campgrounds/new"); 
    });

    // SHOW - shows more info about one campground
    router.get("/:id", function(req, res){
        //find the campground with provided ID
        Campground.findById(req.params.id).populate("comments").exec(function(err, foundCampground){
            if(err){
                console.log(err);
            } else {
                //render show template with that campground
                res.render("campgrounds/show", {campground: foundCampground});
            }
        });
    })
    
    //Middleware
    function isLoggedIn(req, res, next){
        if (req.isAuthenticated()){
            return next();
        }
        res.redirect('/login');
    } 

module.exports = router;

show.ejs

<%- include ('../partials/header') %> 

   <div class="container">
      <div class="row">
         <div class="col-md-3">
            <p class="lead">Yelp Camp</p>
            <div class="list-group">
               <div class="list-group-item active"> Option 1</div>
               <div class="list-group-item"> Option 2</div>
               <div class="list-group-item"> Option 3</div>
            </div>
         </div>
         <div class="col-md-9">
            <div class="img-thumbnail mb-3">
               <img class="img-responsive mb-3"  style="width: 100%" src="<%= campground.image %>">
               <div class="caption-full">
                  <h4 class="float-right">$9.00/night</h4>
                  <h4><a href="#" ><%= campground.name %></a></h4>
                  <p><%= campground.description %></p>
                  <p>
                     <em>Submitted by: <%= campground.author.username %></em>
                 </p>
               </div>
            </div>
            <div class="card bg-light" style="padding: 9px;">
               <div class="text-right mt-3 mr-3">
                  <a class="btn btn-success " href="/campgrounds/<%= campground._id %>/comments/new">Add Comment</a>
               </div>   
               <hr>           
               <% campground.comments.forEach(function(comment){ %>
                  <div class="row ">
                     <div class="col-md-12">
                        <strong> <%= comment.author.username %> </strong>
                        <span class="float-right">10 Days ago</span>
                        <p>
                           <%= comment.text %>
                        </p>
                     </div>
                  </div>  
               <% }) %>
            </div>
         </div>
      </div>

   </div>

<%- include ('../partials/footer') %> 

已更新

重新检查代码后,发现我只是忘记在营地模型中声明author变量

只需一点代码

author :{
        id: {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'User'
        },
        username: String
    },

1 个答案:

答案 0 :(得分:1)

知道了,让我们创建另一个文件,将其命名为例如password.js将所有策略和配置放入该文件中,然后从该文件中导出Passport.js。最后在app.js中,导入该文件,而不是导入实际的password.js

像这样:

passport.serializeUser((user, done) => {
    done(null, user._id);
});

passport.deserializeUser((_id, done) => {
  User.findById( _id, (err, user) => {
    if(err){
        done(null, false, {error:err});
    } else {
        done(null, user);
    }
  });
});