skip to Main Content

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


  1. 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

    Login or Signup to reply.
  2. I suspect your .populate("author") is not working. So when you try to access the book.author.name property the author field is not there. Try passing the model with it. Change to :

    const allBooks = await Book.find({}, "title author")
        .sort({ title: 1 })
        .populate({path: "author", model: Author});
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search