My problem is two-fold, but I think they are both caused by the same issue: my Schema definition and/or Model creation.
I am following this MDN Nodejs tutorial and i cannot figure out:
Why my referenced objects are returning undefined in my layout file, yet I have confirmed that the data is being correctly inserted and queried(as far as i can tell).
My virtual id getter is not working.
Schema Definition:
book.js italize
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const BookSchema = new Schema({
title: {type: String, required: true},
author: {type: Schema.Types.ObjectId, ref: 'Author', required: true},
summary: {type: String, required: true},
isbn: {type:String, required: true},
genre: [{type: Schema.Types.ObjectId, ref: 'Genre'}]
});
//this doesnt seem to be working. returns undefined on the
//object in layout file
BookSchema
.virtual('url')
.get(() => {
return '/catalog/book/' + this._id;
});
module.exports = mongoose.model('Book', BookSchema);
author.js italize
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const AuthorSchema = new Schema({
first_name: {type: String, required: true, max: 100},
family_name: {type: String, required: true, max: 100},
date_of_birth: {type: Date},
date_of_death: {type: Date}
});
//Virtuals
AuthorSchema.virtual('name')
.get(() => {
return this.family_name + ', ' + this.first_name;
});
//create virtual absolute url to obtain instance of this model
AuthorSchema.virtual('url')
.get(() => {
return '/catalog/author/' + this._id;
});
module.exports = mongoose.model('Author', AuthorSchema);
Model Creation:
function authorCreate(first_name, family_name, d_birth, d_death, cb) {
authordetail = {first_name:first_name , family_name: family_name }
if (d_birth != false) authordetail.date_of_birth = d_birth
if (d_death != false) authordetail.date_of_death = d_death
var author = new Author(authordetail);
author.save(function (err) {
if (err) {
cb(err, null)
return
}
console.log('New Author: ' + author);
authors.push(author._id)
cb(null, author)
} );
}
function bookCreate(title, summary, isbn, author, genre, cb) {
bookdetail = {
title: title,
summary: summary,
author: author,
isbn: isbn
}
if (genre != false) bookdetail.genre = genre
var book = new Book(bookdetail);
book.save(function (err) {
if (err) {
cb(err, null)
return
}
console.log('New Book: ' + book);
books.push(book._id)
cb(null, book)
} );
}
controller.js:
// Display list of all books.
exports.book_list = function(req, res) {
Book.find({})
.populate('author')//this seems to work
.exec(function (err, list_books) {
if (err) { return next(err); }
//Successful, so render
for(var b in list_books){
console.log('author id: ' + list_books[b].author._id);//as evidenced here
}
//but the author object is undefined when rendered
res.render('book_list', { title: 'Book List', book_list: list_books });
});
};
layout.pug:
extends layout
block content
h1= title
//url and author undefined here
ul
each book in book_list
li
a(href=book.url) #{book.title}
| #{book.author.name}
else
li There are no books.
Screenshot:
Tools:
Node + Express js
Pug
mLab free tier
I am completely new to Mongoose DB & Pug and know only as much as the primers in the tutorial have taught and explicitly pointed to as further reading.
Let me know if you need any more information. Thanks
I looks like my problem was usage of fat arrow functions. Changing those to regular function()
syntax fixed the issue.
This answer confirmed that its a support issue in nodejs.