Search code examples
node.jsmongodbapachepugmonk

NodeJS, MongoDB, Jade/Pug - Cannot read property 'length' of undefined on Apache(localhost works)


I'm having some trouble to connect my app in the server(hosted by KingHost).. On local machine, it works perfectly On the server, the one thing I do is change the database from localhost to the server, and the port from 3000 to my server...

When I run the app on the server I get:

TypeError: /home/rsracingufrgs/apps_nodejs/views/index.jade:316
    314|                         h3.section-heading Capitão
    315|                 .row
  > 316|                     each membro, i in capitao
    317|                         .col-sm-4
    318|                             .team-member
    319|                                 img.mx-auto.rounded-circle(src='/img/team/#{membro.imagem}', alt='#{membro.nome}')

Cannot read property 'length' of undefined
    at eval (eval at <anonymous> (/home/rsracingufrgs/apps_nodejs/node_modules/jade/lib/index.js:218:8), <anonymous>:1755:31)
    at eval (eval at <anonymous> (/home/rsracingufrgs/apps_nodejs/node_modules/jade/lib/index.js:218:8), <anonymous>:1888:4)
    at eval (eval at <anonymous> (/home/rsracingufrgs/apps_nodejs/node_modules/jade/lib/index.js:218:8), <anonymous>:6670:22)
    at res (/home/rsracingufrgs/apps_nodejs/node_modules/jade/lib/index.js:219:38)
    at Object.exports.renderFile (/home/rsracingufrgs/apps_nodejs/node_modules/jade/lib/index.js:380:38)
    at Object.exports.renderFile (/home/rsracingufrgs/apps_nodejs/node_modules/jade/lib/index.js:370:21)
    at View.exports.__express [as engine] (/home/rsracingufrgs/apps_nodejs/node_modules/jade/lib/index.js:417:11)
    at View.render (/home/rsracingufrgs/apps_nodejs/node_modules/express/lib/view.js:127:8)
    at tryRender (/home/rsracingufrgs/apps_nodejs/node_modules/express/lib/application.js:640:10)
    at EventEmitter.render (/home/rsracingufrgs/apps_nodejs/node_modules/express/lib/application.js:592:3)

But on localhost it works perfectly... The databases are equal(see image below) database server(big), database localhost(prompt)

The code(what changes between server and localhost)

var db = monk('localhost:27017/rsracingufrgs') //localhost
//var db = monk('mongodb.rsracingufrgs.com.br/rsracingufrgs01'); //server

var porta = 3000 // localhost
//var porta = 21031 //server

The call to the database:

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

    const db = req.db;
    const async = require("async")

    const names = ['capitao',...]

    const collections = names.map(name => db.get(name) )

    const functions = collections.map(collection => {
        return done => collection.find( {}, done )
    })

    async.series( functions, (err, results) => {
        // "results" is now an array containing [ docs1, docs2, .. ]
        res.render('index', {
            env: env,
            capitao: results[0],
            ...
        });
    })
});

the Jade code(works on localhost):

        .row
            each membro, i in capitao
                .col-sm-4
                    .team-member
                        img.mx-auto.rounded-circle(src='/img/team/#{membro.imagem}', alt='#{membro.nome}')
                        h4 #{membro.nome}
                        p.text-muted #{membro.curso}
                        ul.list-inline.social-buttons
                            li.list-inline-item
                                a(href="mailto:#{membro.email}")
                                    i.fa.fa-envelope

Other things that could be important:

  • node version: 6.11.1
  • npm version: 3.10.10
  • mongodb version(installed from npm on server): 2.2.31 Dependencies from package.json
"dependencies": {
    "async": "^2.5.0",
    "body-parser": "^1.18.1",
    "connect-ensure-login": "^0.1.1",
    "cookie-parser": "^1.4.3",
    "dotenv": "^4.0.0",
    "express": "^4.15.4",
    "express-session": "^1.15.5",
    "jade": "^1.11.0",
    "logger": "0.0.1",
    "mongo": "^0.1.0",
    "mongodb": "^2.2.31",
    "mongoose": "^4.11.11",
    "monk": "^6.0.4",
    "morgan": "^1.8.2",
    "passport": "^0.4.0",
    "passport-auth0": "^0.6.0",
    "path": "^0.12.7",
    "request": "^2.81.0"
  }

Edit: using the debug code that @Sridhar provided, I got the following result:

{ MongoError: not authorized on rsracingufrgs01 to execute command { find: "capitao", filter: {}, projection: {} }
    at Function.MongoError.create (/home/rsracingufrgs/apps_nodejs/node_modules/mongodb-core/lib/error.js:31:11)
    at queryCallback (/home/rsracingufrgs/apps_nodejs/node_modules/mongodb-core/lib/cursor.js:212:36)
    at /home/rsracingufrgs/apps_nodejs/node_modules/mongodb-core/lib/connection/pool.js:469:18
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickCallback (internal/process/next_tick.js:104:9)
  name: 'MongoError',
  message: 'not authorized on rsracingufrgs01 to execute command { find: "capitao", filter: {}, projection: {} }',
  ok: 0,
  errmsg: 'not authorized on rsracingufrgs01 to execute command { find: "capitao", filter: {}, projection: {} }',
  code: 13 }

Solution

  • Update

    As per mongodb error codes, 13 corresponds to Unauthorized. You can check MongoDB not authorized for query - code 13 for fixing it.


    Original answer

    Cannot read property 'length' of undefined

    It clearly states that .length is called on the undefined variable. So, I suspect your result[0] will be undefined. If you log results, you will know more about the issue.

    'use strict';
    
    let _ = require('lodash');
    
    ....
    
    async.series(functions, (err, results) => {
        if (err || _.isUndefined(results)) {
            //general error handling
            console.log(err);
            return res.render('index', {
                env: env,
                capitao: []
            });
        }
        res.render('index', {
            env: env,
            capitao: _.isUndefined(results[0]) ? [] : result[0],
            ...
        });
    });