Error encountered when attempting to populate nested fields in Mongoose

Recently, I encountered an error while trying to add comments to my posts by using nested populate for mongoose. Initially, everything was working fine when I only pre-populated user data. However, as soon as I implemented nested populate, I started receiving an error stating "posts is not iterable". To provide more clarity on this issue, I have shared a snippet of my code below.

Error

TypeError: /home/vivek/Vivek/CN WEBD/codel/views/home.ejs:16
    14|     <div id="posts-list-container">
    15|         <ul>
 >> 16|             <% for (post of posts){ %>
    17|                 
    18|                 
    19|             <li>

posts is not iterable
    at eval (eval at compile (/home/vivek/Vivek/CN WEBD/codel/node_modules/ejs/lib/ejs.js:662:12), <anonymous>:21:21)
    at home (/home/vivek/Vivek/CN WEBD/codel/node_modules/ejs/lib/ejs.js:692:17)
    ...

// Remaining error stack trace omitted for brevity

Home_controller.js:

const Post = require('../models/post');

module.exports.home = function(req, res){

    Post.find({})
    .populate('user').
    populate({
            path: 'comments',
            populate: {
                path: 'user'
            }
        })
        .exec(function(err, posts){
            return res.render('home', {
            title: "Home",
            posts: posts
        });
    })

};

Home.ejs: where i am trying to fetch the data

   <div id="posts-list-container">
        <ul>
            <% for (post of posts ){ %>
                
                
            <li>
                <p><%= post.user.name %>
                <%= post.content %>
                </p>
                <div class="post-comments">
                    <% if (locals.user){ %> 
                        <form action="/comments/create" method="POST">
                            <input type="text" name="content" placeholder="type here to comment">
                            <input type="hidden" name="post" value="<%= post._id%>">
                            <input type="submit" value="Add comment">
                        </form>    
                    <%}%>

                    <div class="post-comment-list">
                        <ul id="post-comments-<%= post._id %>">
                                <% for (comment of posts.comments){ %>
                                    <p>
                                        <%= comment.content %>
                                        <br>
                                        <small>
                                            <%= comment.user.name %>
                                        </small>
                                    </p>
                                <%} %>
                        </ul>
                    </div>


                </div>
            </li>    
            
            <% }%>


        </ul>

    </div>

CommentsSchema model

const mongoose = require('mongoose');


const commentScehma = new mongoose.Schema({
    content:{
        type: String,
        required: true
    },
    //comment belogns to user
    user: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    },
    post: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Post'
    }
},{
    timestamps: true
})

const Comment = mongoose.model('Comment', commentScehma)
module.exports = Comment;

Post Schema Model

const mongoose = require('mongoose');

const postSchema = new mongoose.Schema({
    content: {
        type: String,
        required: true
    },
    user: {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    },
    // inclue the array of id's of all comments in this post schema itself
    comments: [
        {
           type: mongoose.Schema.Types.ObjectId,
           ref: 'comment'  
        }
    ]


},{
    timestamps: true
});


const Post = mongoose.model('Post', postSchema);
module.exports = Post;   

Answer №1

It seems that the server.js (or any starting point in your app) was not provided, making it uncertain if my example will offer any guidance. However, I managed to successfully get the controller to deliver data to the view. Here is how I implemented my controller...

./controllers/home.js

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


router.get('/', (req, res, err) => {
    posts.find().populate("comments").exec().then(results => {
        console.log(results);
        return res.render('pages/home', { posts: results });
    });
});


module.exports = router;

...and this is how my view looks like...

./views/pages/home.ejs

<!DOCTYPE html>
<html lang="en">
<head>
  <%- include('../partials/head'); %>
</head>
<body class="container">

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

<main>
  <div class="jumbotron">
    <h1>testing</h1>

     <% for (post of posts){ %>
          <li><%= post._id %></li>
          <ul>
              <% for (comments of post.comments) { %>
                  <li><%= comments.content %></li>
              
              <% } %>
          </ul>
     <% }%>

     </ul>
  </div>
</main>

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

</body>
</html>

... and here is the rendered page...

Check it out here!

My documents are divided into two collections:

  • Posts
  • Comments

Posts

Enterprise replSet [primary] nodetest> db.Posts.find()
[
  {
    _id: ObjectId("61241efd7a37aa7000116773"),
    comments: [
      ObjectId("61241efd7a37aa7000116770"),
      ObjectId("61241efd7a37aa7000116771"),
      ObjectId("61241efd7a37aa7000116772")
    ],
    content: 'my post content',
    createdAt: ISODate("2021-08-23T22:19:41.193Z"),
    updatedAt: ISODate("2021-08-23T22:19:41.193Z"),
    __v: 0
  },
  {
    _id: ObjectId("61241f892b030d704c728176"),
    comments: [
      ObjectId("61241f892b030d704c728173"),
      ObjectId("61241f892b030d704c728174"),
      ObjectId("61241f892b030d704c728175")
    ],
    content: 'my post content',
    createdAt: ISODate("2021-08-23T22:22:01.949Z"),
    updatedAt: ISODate("2021-08-23T22:22:01.949Z"),
    __v: 0
  }
]

Comments

Enterprise replSet [primary] nodetest> db.Comments.find()
[
  {
    _id: ObjectId("61241efd7a37aa7000116770"),
    content: 'Some loopy content 0',
    createdAt: ISODate("2021-08-23T22:19:41.193Z"),
    updatedAt: ISODate("2021-08-23T22:19:41.193Z"),
    __v: 0
  },
  {
    _id: ObjectId("61241efd7a37aa7000116771"),
    content: 'Some loopy content 1',
    createdAt: ISODate("2021-08-23T22:19:41.193Z"),
    updatedAt: ISODate("2021-08-23T22:19:41.193Z"),
    __v: 0
  },
  {
    _id: ObjectId("61241efd7a37aa7000116772"),
    content: 'Some loopy content 2',
    createdAt: ISODate("2021-08-23T22:19:41.193Z"),
    updatedAt: ISODate("2021-08-23T22:19:41.193Z"),
    __v: 0
  },
  {
    _id: ObjectId("61241f892b030d704c728173"),
    content: 'Some loopy content 0',
    createdAt: ISODate("2021-08-23T22:22:01.948Z"),
    updatedAt: ISODate("2021-08-23T22:22:01.948Z"),
    __v: 0
  },
  {
    _id: ObjectId("61241f892b030d704c728174"),
    content: 'Some loopy content 1',
    createdAt: ISODate("2021-08-23T22:22:01.949Z"),
    updatedAt: ISODate("2021-08-23T22:22:01.949Z"),
    __v: 0
  },
  {
    _id: ObjectId("61241f892b030d704c728175"),
    content: 'Some loopy content 2',
    createdAt: ISODate("2021-08-23T22:22:01.949Z"),
    updatedAt: ISODate("2021-08-23T22:22:01.949Z"),
    __v: 0
  }
]

General Comments:

It appears that there is an attempt to establish bi-directional references between collections, implying a parent-child relationship where one post can have multiple comments. The post documents maintain an array of ObjectIDs corresponding to related child comments, while the Comment document includes the parent Post ObjectID as well, defining relationships from both perspectives.

In the absence of sample data, it's challenging to assess potential misalignments. Additionally, upon reviewing your controller, it doesn't seem to render a view which may result in data unavailability leading to encountered errors. Referencing my controller example should illuminate the process of passing data between the controller and view, enabling seamless functionality.

To facilitate efficient assistance, consider providing a simplified version of the issue with filenames, paths, sample data, and seek clarification where necessary. By enhancing clarity on your end, more targeted support could be extended.

I trust these examples offer valuable insights. Clearer communication on your part enhances the troubleshooting process further.

Answer №2

I identified the problem in the post schema model, where I mistakenly referenced 'comment' instead of 'Comment'.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieving a subset of JSON data from a larger JSON object in a Node.js environment

I'm working with a JSON object structured like this: [ { "id": "458712e247328e4ebfafeb4d922b", "value": [ 1 ], "location": null, "metadata": null, "at": "2015-07-16T16:33:39.113Z" }, { "id": "1ghj78d8220734c00ab941 ...

Troubleshooting issue with parsing MySQL data in HTML table using Node.js

Seeking Assistance! I am currently in the process of developing a node file that displays data from MySQL on an HTML page with a search bar. My issue is that sometimes when I run the code, enter something into the search bar and hit the button, it works s ...

What is the best way to interact with a checkbox that has a label using Selenium in Node.js?

My HTML document contains multiple checkbox classes with different texts for each checkbox name. Here is a snippet of the HTML code: <div class="col-md-12 syllabus-div-1"> <h4 class="vertical-spacing">Coaching<i class="fa fa-graduation- ...

React component is unable to identify prop

I'm attempting to send an array of objects from the main App.js file to a smaller component using props. However, for some reason, the prop is not being recognized within the smaller component file. https://i.stack.imgur.com/WuyFr.png https://i.stac ...

Creating a bot that will only respond once when a user sends multiple photos simultaneously

I'm currently working on a Telegram bot using nodejs. I am utilizing the node-telegram-bot-api library and have implemented the on('photo') method to handle when a user sends a photo to my bot. However, I am facing an issue where if a user ...

Control the frequency of server requests within a set limit

Currently, I am utilizing the request-sync library to fetch data from a specific site's API. This is how my code looks: let req = request('GET', LINK, { 'headers': { 'Accept' ...

"Utilize axios in React to interpret and handle error bodies captured through parsing as a ReadableStream

When I sent a post request using axios in a React form to a PHP server, I encountered an issue where the error returned a ReadableStream in its body. However, when I used Postman, I did not have this problem and received readable errors instead. How can I ...

Encountering a self-signed certificate in the certificate chain issue while implementing the Watson Assistant SDK with Node.js

I've been working with the IBM Watson API and its node.js SDK. However, I'm encountering an issue where calling the Watson API using the node.js SDK consistently results in the following error: { Error: self signed certificate in certificate cha ...

Tips for resolving an issue with mongoose Model.create becoming unresponsive indefinitely

I'm having trouble understanding why my mongoose Model.create operation isn't completing successfully. The same connection is working well with other controller functions. vscode postman I am attempting to create a new document, but my code s ...

The call stack size has been exceeded, even after removing node_modules and package-lock.json and attempting to run 'npm i'

Sorry for repeating the 'maximum call stack size exceeded' issue, but I've exhausted almost every suggestion on stackoverflow. Versions: node v.14.19.0 npm v.6.14.16 Here is the error log: > <a href="/cdn-cgi/l/email-protection" clas ...

Searching for variables within files using Node.js and constructing an object from the results

Trying to figure out how to streamline this process. Here's the directory structure I'm working with: src/ modules/ clients/ i18n/ en-US.ts tasks/ i18n/ en-US.ts So, ea ...

How to optimize NodeJS global modules caching in AWS CodeBuild

Wondering how to store NodeJS global modules in AWS CodeBuild for quick access? I'm using LernaJS for my repository management and every time a build is initiated, I have to install it using the command npm install -g lerna (which takes around 30 sec ...

Prevent users from viewing or editing profiles of other users

I need to enhance the security of my application by restricting users from accessing profiles of other users. route.js router.get('/currentUser/:username', userAuth, (req, res) => { User.findOne({ username: req.params.username }).the ...

Encountering RangeError with the Number() function on my express.js server

I'm working with an HTML form that looks like this: <form class="" action="/" method="post"> <input type="text" name="num1" placeholder="First Number"> <input type= ...

Every time I try to access a Heroku deployed link, I encounter a 500 error (Internal Server Error)

Whenever I use http://localhost:5000/login everything works perfectly fine. However, when I utilize the live link , an error occurs stating POST 500 (Internal Server Error) The code snippet below using the live Heroku link: This particular code is not fu ...

Step-by-step guide on generating a fluid list with Express and HTML

Looking to create a dynamic list by fetching data from a JSON file. I want the list items to redirect me to specific content based on their IDs when clicked. However, my current approach is not working as expected, and the list needs to be truly dynamic. ...

File download is initiated through an Ajax response

Utilizing Polymer's iron-ajax element, I am making an XMLHTTPRequest to a server endpoint: <iron-ajax id="ajax" method="POST" url="/export/" params='' handle-as="json" on-response="handleResponse" </iron-ajax> The resp ...

When it comes to Node.js and npm, which term is more suitable: "package" or "module"?

I'm feeling a bit puzzled - is `npm` considered a package manager, while `Node.js` uses modules? When installing or creating your own... umm, module or package? How do you decide which term to use and when? ...

A variation in the results of a query can be observed when using MERN stack and

I'm encountering an issue with my MERN app. Everything works fine on my localhost, but when it's hosted on a remote server, the database returns different data. When I send a query to http://:8080/getreports?date=40-2020 (no matter what the ser ...

Unable to locate a type definition file for module 'vue-xxx'

I keep encountering an error whenever I attempt to add a 3rd party Vue.js library to my project: Could not find a declaration file for module 'vue-xxx' Libraries like 'vue-treeselect', 'vue-select', and 'vue-multiselect ...