CHATRAPAL HEDAU
CHATRAPAL HEDAU

Reputation: 21

Cannot read property 'username' of undefined

I've been trying to add user associations to the /campgrounds but suddenly this error came up

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)

These are the following files in which I put a code of user associations in router.post the method in campground.js file and through the show.ejs file I want to display the username

Please help me out

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') %> 

UPDATED

After rechecking my code, found that i just forgotten to declare the author variable in campground models

just a little bit of code

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

Upvotes: 2

Views: 507

Answers (1)

asfandyar24
asfandyar24

Reputation: 84

Got it, Let's create other file, name it for example passport.js Put all strategies and configurations into that file, and export passport.js from that file. And finally in app.js, import that file instead of importing actual passport.js

like this :

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);
    }
  });
});

Upvotes: 1

Related Questions