Share On Twitter Facebook Google+ LinkedIn Pinterest Tumblr Reddit
Question

TypeError: Cannot read property forEach of undefined in node.js

Tags: node.js javascript mongodb mongoose
Date:
Status:Resolved
Question Id:29

I'm pretty new to Nodejs+Express. I have to connect my Nodejs+Express app to MongoDB which I'm struggling to do. This TypeError: Cannot read property 'forEach' of undefined has been showing up. I'm following this tutorial https://www.youtube.com/watch?v=yH593K9fYvE&feature=youtu.be There's a simple table in my MongoDB database with ids and names which I have created. Appreciate any kind of help! I believe there's an issue in the db.ejb file. But I'm not so sure.

This is my server.js code:

const express = require('express');
const mongoose = require('mongoose');
const app = express();
let port=process.env.PORT || 4000;
const ejs = require('ejs');

app.set('view engine', 'ejs');
//mongoose
mongoose.connect('mongodb+srv://cluster0:83QY2ecAEcLVDeQI@cluster0.srrxv.mongodb.net/newdataDB?retryWrites=true&w=majority');

let dataSchema = new mongoose.Schema({
    id: String,
    name: String
})
const Data = mongoose.model('Data', dataSchema);
//api routes
app.get('/',  (req, res) => {
    Data.find({}, function(err, r){
        res.render('db', {
            results : r
        })
    })
})

app.listen(port, ()=>{
    console.log('Example app is listening on port http://localhost:${port}')}); ```

This is the views/pages/db.ejs code:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class="container">
    <h2>Database Results</h2>
    <ul>
        <% results.forEach(function(r) { %>
            <li><%= r.id %> - <%= r.name %></li>
        <% }); %>
    </ul>
</div>
</body>
</html>
Answer
Date:
Correct:Yes

Okay so here it goes. First, TypeError: Cannot read property 'forEach' of undefined means that the results array is undefined. It's not due to the error in the db.ejs file. You should conclude that the results array you're sending in your view is undefined.(irrelevant but still good to know- the values like results which you pass into the views are called locals).

So get out from the db.ejs and let's head to the server.js file.

Let's take a look at the following code:

//mongoose
mongoose.connect('mongodb+srv://cluster0:83QY2ecAEcLVDeQI@cluster0.srrxv.mongodb.net/newdataDB?retryWrites=true&w=majority');

Now don't get me wrong. If you didn't say you were following a tutorial, I wouldn't even dare to consider this a possibility. But since you said that, I think you are very new to all this, and the following could be a possibility.

You didn't replace the MONGODBURI with your own inside mongoose.connect function. I.e. your used the example connection string and so your node app isn't connecting to a valid database. Replace the connection string with your own inside the mongoose.connect function. I'd say it's most probably due to this, because otherwise I don't see any problem in your code.

Refer to the following link to know more about connecting to mongo DB atlas:Mongoose connecting to mongoDB

EDIT And if you're using your own mongo DB connection string, then try modifying :

...
 Data.find({}, function(err, r){
        res.render('db', {
            results : r
        })
...

to the following:

...
 Data.find({}, function(err, r){
        if(err) throw err;
        res.render('db', {
            results : r
        })
...

I'm adding checking for error. You should never miss that part out. In future, you should do something meaningful(like sending response with error message like "Something went wrong.", which you can display in your view) in case of an error. For now, I'm just logging it into the console. See what error pops up and maybe you can figure it out.

This is the only other possiblity I could find. Because if you have an error querying the database, the r will be undefined. And since you haven't checked for errors, the same r will be send to the locals of your view.

Your Answer

Review Your Answer