I am following The Odin’s project local library tutorial (Express app).
Here is my code (only relevant parts):
in routes/catalog.js I have this
router.get("/books", book_controller.book_list);
models/book.js
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"}],
});
BookSchema.virtual("url").get(function(){
return `/catalog/book/${this._id}`
})
module.exports = mongoose.model("Book",BookSchema);
controllers/bookController.js
const Book = require("../models/book");
const Author = require("../models/author");
const Genre = require("../models/genre");
const BookInstance = require("../models/bookinstance");
const asyncHandler = require("express-async-handler");
exports.index = asyncHandler(async (req, res, next) => {
// Get details of books, book instances, authors and genre counts (in parallel)
const [
numBooks,
numBookInstances,
numAvailableBookInstances,
numAuthors,
numGenres,
] = await Promise.all([
Book.countDocuments({}).exec(),
BookInstance.countDocuments({}).exec(),
BookInstance.countDocuments({ status: "Available" }).exec(),
Author.countDocuments({}).exec(),
Genre.countDocuments({}).exec(),
]);
res.render("index", {
title: "Local Library Home",
book_count: numBooks,
book_instance_count: numBookInstances,
book_instance_available_count: numAvailableBookInstances,
author_count: numAuthors,
genre_count: numGenres,
});
});
exports.book_list = asyncHandler(async (req, res, next) => {
const allBooks = await Book.find({}, "title author")
.sort({ title: 1 })
.populate("author")
.exec();
res.render("book_list", { title: "Book List", book_list: allBooks });
});
Now here is the file which causes problems: views/book_list.pug
extends layout
block content
h1= title
ul
each book in book_list
li
a(href=book.url) #{book.title}
| (#{book.author.name})
else
li There are no books.
I have no idea why is that causing an error? that clearly should work and it works in the tutorial so I must have something wrong here, but for the love of god I can’t find a mistake.
The error appears when I go to the route /catalog/books
D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugviewsbook_list.pug:10 8| li 9| a(href=book.url) #{book.title} > 10| | (#{book.author.name}) 11| 12| else 13| li There are no books. Cannot read properties of null (reading 'name')
TypeError: D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugviewsbook_list.pug:10
8| li
9| a(href=book.url) #{book.title}
> 10| | (#{book.author.name})
11|
12| else
13| li There are no books.
Cannot read properties of null (reading 'name')
at eval (eval at wrap (D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugnode_modulespug-runtimewrap.js:6:10), <anonymous>:120:69)
at eval (eval at wrap (D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugnode_modulespug-runtimewrap.js:6:10), <anonymous>:155:4)
at template (eval at wrap (D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugnode_modulespug-runtimewrap.js:6:10), <anonymous>:157:155)
at exports.renderFile (D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugnode_modulespuglibindex.js:418:38)
at exports.renderFile (D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugnode_modulespuglibindex.js:408:21)
at exports.__express [as engine] (D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugnode_modulespuglibindex.js:455:11)
at View.render (D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugnode_modulesexpresslibview.js:135:8)
at tryRender (D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugnode_modulesexpresslibapplication.js:640:10)
at Function.render (D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugnode_modulesexpresslibapplication.js:592:3)
at ServerResponse.render (D:THE ODIN PROJECTNodeJSCourseexpress-locallib-pugnode_modulesexpresslibresponse.js:1008:7)
I was going all by myself and just looking at the general idea. When I encountered this for the first time I thought it’s because I’m using EJS and the tutorial goes by Pug. So I quickly switched the files and view engine to pug, but it didn’t help at all. Then I thought that it might be compatibility problem so I completely cloned this project by I generating the project as pug natively and copying the rest of the files. The error still exists – still at the same time.
When I remove book_list.pug there is no error (obviously it is caused by the
> 10| | (#{book.author.name})
line, however I have no idea why is that causing problems on my part, and works in the tutorial? I can’t find the solution to this either.
2
Answers
check your
Author model in your project
does it contain Name field or not
or maybe name is empty please check mongodb check data is present in Author schema or not
I suspect your
.populate("author")
is not working. So when you try to access thebook.author.name
property theauthor
field is not there. Try passing the model with it. Change to :