kevinius kevinius - 1 year ago 91
Node.js Question

node.js: JSON dot notation + access array key

I have a site setup using node.js, express, mongoDB & mongoose. Mongoose is giving me an array that contains this:

[ { title: 'HTML in depth',
author: 'kevin vanhove',
_id: 53039f264a6324978c70084b,
chapters:
[ { _id: 53039f264a6324978c70084d,
content: '/jow',
title: 'History of HTML' },
{ _id: 53039f264a6324978c70084c,
content: '/w3c',
title: 'What is the W3C' } ],
__v: 0 } ]


I'm getting this result in my terminal using this code:

function indexData(books){

console.log(books)

res.render("index.html", {context:books, partials:{footer:"footer", header:"header"}})


}

Now i'm trying to access the value in chapters[0].title, but i'm getting an error:

console.log(books[0].chapters[0].title)

TypeError: Cannot read property '0' of undefined


I'm confused here, am i accessing the value using the right dot notation?

UPDATE 1: complete terminal output

24 Feb 10:56:47 - [nodemon] restarting due to changes...
24 Feb 10:56:47 - [nodemon] starting `node app.js`
Mongoose: books.find({}) { fields: undefined }

/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/routes/routes.js:45
console.log(books[0].chapters[0].title)
^
TypeError: Cannot read property '0' of undefined
at indexData (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/routes/routes.js:45:32)
at Promise.<anonymous> (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/routes/routes.js:37:31)
at Promise.<anonymous> (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/node_modules/mpromise/lib/promise.js:177:8)
at Promise.EventEmitter.emit (events.js:95:17)
at Promise.emit (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/node_modules/mpromise/lib/promise.js:84:38)
at Promise.fulfill (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/node_modules/mpromise/lib/promise.js:97:20)
at /Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/lib/query.js:1052:26
at model.Document.init (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/lib/document.js:250:11)
at completeMany (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/lib/query.js:1050:12)
at Object.cb (/Users/kevinvanhove/Documents/work/projects/basing/business/klanten/javascript/nodeJS/express/basing/node_modules/mongoose/lib/query.js:1017:11)
24 Feb 10:56:49 - [nodemon] app crashed - waiting for file changes before starting...


Partial solution:

I was trying to get to the chapters data. Updating my mongoose schema to include the chapters data did the trick.

var booksSchema = new mongoose.Schema({
title: String,
author: String,
chapters: [
{
title: String,
content: String
}
]

});

Answer Source

This doesn't work an that way on the Mongoose (server) side. The result from find() is a cursor that you need to either iterate or convert via toArray from the native driver part. Something like this

(Assuming Schema Books):

Books.collection.find({}).toArray(function(err, results) {

  // results is an array that you can do something with here.

});

Of course if you have defined additional Schema for arrays and their documents that are not embedded, then this is going to hurt a bit more and you need to use the iterative methods to get your results as an array.

If you want specific items from your books and sub-items within, then you would be better of tuning your find query using the operators rather than returning all results. Or even the aggregation pipeline may be of some help.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download