Home > Software engineering >  Why is find({}) returning undefined?
Why is find({}) returning undefined?

Time:10-26

Hi I am making a basic social application that as of right now has an Account and a Post model.

I am able to display the Account model plus more, but I am having issues with the Post model specifically when I go to display all the posts.

The mongoose function Post.find({}).exec(function(err, posts) in allPosts.js keeps returning undefined even when I have posts in the database.

NOTE: I can successfully post to the posts collection just cant read from them.

I am able to display all accounts but not all posts.


Update: I can now create a post then get redirected back to the allPosts.pug page and see all posts except for the post that was just created, take a look at addNewPost.js.

I would like to be able to go from my login page and have all the post displayed check out index.js

/* Account.js */

const mongoose = require("mongoose")

const Account = mongoose.model("Account", {
    name: String,
    lastName: String,
    email: {type: String, unique: true, lowercase: true, required: true},
    phoneNumber: String,
    password: String
})

module.exports = Account
/* Post.js */

const mongoose = require("mongoose")

const Post = mongoose.model("Post", {
    emailId: {type: String, required: true},
    postTitle: {type: String, required: true},
    postMessage: {type: String, required: true},
    datePosted: {type: Date, default: Date.now},
})

module.exports = Post
/* allPosts.js */

var express = require('express');
var router = express.Router();
const Account = require("../models/account")
const Post = require("../models/post")

/* GET all posts page. */
router.get('/', function(req, res, next) {
    Post.find({}).exec(function(err, posts) {
        res.render("allPosts", {title: "Social Application", posts: posts})
    })
})

module.exports = router;
/* allPosts.pug */

extends layout 

block content 
    h1 #{title}

    if posts === undefined
        h1 No posts to show here 
    else 
        each post in posts
            div(class="container")
                div(class="jumbotron")
                    h1= post.postTitle 
                    h1= post.postMessage
    br
    
    a(href="/addNewPost"): button(class="btn btn-primary float-end") Add post
    a(href="/logout"): button(class="btn btn-primary float-end") Logout
/* addNewPost.js */

var express = require('express');
const Post = require('../models/post');
var router = express.Router();

/* GET all posts page. */
router.get('/', function(req, res, next) {
    res.render("addNewPost", {title: "Social Application"})
});

router.post('/', function(req, res, next) {
    var emailId = req.session.email
    var postTitle = req.body.postTitle
    var postMessage = req.body.postMessage

    var postData = {
        emailId: emailId,
        postTitle: postTitle,
        postMessage: postMessage
    }

    var aPost = new Post(postData)
    aPost.save(function(err) {
        if (err) {
            console.log(err)
        } else {
            console.log("Post saved successfully !")
        }
    })

    Post.find({}).exec(function(err, posts) {
        res.render("allPosts", {title: "All posts", posts: posts})
    })
})

module.exports = router;
/* index.js */

var express = require('express');
var router = express.Router();
const Account = require("../models/account")
const bcrypt = require("bcrypt");

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: "Social Application" });
});

/* POST home page */
router.post('/', function(req, res, next) {
  var email = req.body.email
  var password = req.body.password

  Account.findOne({email:email}).exec(function(err, account) {
    if (account) {
      if (bcrypt.compareSync(password, account.password)) {
        req.session.email = account.email
        req.session.userLoggedIn = true
        res.render("allPosts", {title: "All Posts"})
      } else {
        res.render("index", {error: "Your credentials are incorrect !", title: "Social Application"})
      }
    } else {
      res.render("index", {error: "This account does not exist !", title: "Social Application"})
    }
  })
})

module.exports = router;
/* Trace */

TypeError: C:\Users\bmxfi\Desktop\code\NodeJavascript\SocialApplication\SocialApplication\views\allPosts.pug:7
    5| 
    6|     
  > 7|     each post in posts
    8|         div(class="container")
    9|             div(class="jumbotron")
    10|                 h1= post.postTitle 

Cannot read property 'length' of undefined
    at eval (eval at wrap (C:\Users\bmxfi\node_modules\pug\node_modules\pug-runtime\wrap.js:6:10), <anonymous>:36:32)
    at eval (eval at wrap (C:\Users\bmxfi\node_modules\pug\node_modules\pug-runtime\wrap.js:6:10), <anonymous>:71:4)
    at template (eval at wrap (C:\Users\bmxfi\node_modules\pug\node_modules\pug-runtime\wrap.js:6:10), <anonymous>:93:7)
    at Object.exports.renderFile (C:\Users\bmxfi\node_modules\pug\lib\index.js:454:38)
    at Object.exports.renderFile (C:\Users\bmxfi\node_modules\pug\lib\index.js:444:21)
    at View.exports.__express [as engine] (C:\Users\bmxfi\node_modules\pug\lib\index.js:493:11)
    at View.render (C:\Users\bmxfi\node_modules\express\lib\view.js:135:8)
    at tryRender (C:\Users\bmxfi\node_modules\express\lib\application.js:640:10)
    at Function.render (C:\Users\bmxfi\node_modules\express\lib\application.js:592:3)
    at ServerResponse.render (C:\Users\bmxfi\node_modules\express\lib\response.js:1012:7)

CodePudding user response:

Exec returns the promise and you are calling it with the callback.

const posts = Post.find({}).exec(); // this will be the promise
// now use then/catch to get the results, you can use
// async/await, it's the choice

posts.then((res) => console.log(res)).catch((e) => console.log(e));

You should do this:

router.get('/', function(req, res, next) {

const posts = Post.find({}).exec();
  posts.then((result) => { 
     console.log(result); // check the res, it should now be populated.
      res.render("allPosts", {title: "Social Application", posts: result})
  }).catch((e) => console.log(e));

})

Check here for more details.

CodePudding user response:

The fix is below just had to redirect("allPosts") to the view instead of res.render("allPosts", {title: "Social Application")

/* index.js */

var express = require('express');
var router = express.Router();
const Account = require("../models/account")
const bcrypt = require("bcrypt");

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: "Social Application" });
});

/* POST home page */
router.post('/', function(req, res, next) {
  var email = req.body.email
  var password = req.body.password

  Account.findOne({email:email}).exec(function(err, account) {
    if (account) {
      if (bcrypt.compareSync(password, account.password)) {
        req.session.email = account.email
        req.session.userLoggedIn = true
        res.redirect("allPosts")
      } else {
        res.render("index", {error: "Your credentials are incorrect !", title: "Social Application"})
      }
    } else {
      res.render("index", {error: "This account does not exist !", title: "Social Application"})
    }
  })
})

module.exports = router;
/* addNewPost.js */

var express = require('express');
const Post = require('../models/post');
var router = express.Router();

/* GET all posts page. */
router.get('/', function(req, res, next) {
    res.render("addNewPost", {title: "Social Application"})
});

router.post('/', function(req, res, next) {
    var emailId = req.session.email
    var postTitle = req.body.postTitle
    var postMessage = req.body.postMessage

    var postData = {
        emailId: emailId,
        postTitle: postTitle,
        postMessage: postMessage
    }

    var aPost = new Post(postData)
    aPost.save(function(err) {
        if (err) {
            console.log(err)
        } else {
            console.log("Post saved successfully !")
        }
    })

    res.redirect("allPosts")
})

module.exports = router;
  • Related