Search code examples
node.jsmongodbexpressmongoosepug

mongoose find results not refreshing


I'm working with express/jade/mongodb to create a site with a db (pretty new in this). I am retrieving a list from the db using 'mongoose find' during the get method using this function:

function getBookList(Book, req, callback){
  Book.find({'username': req.user.username}, 'bookTitle author', function(err, userBooks) {
    if (err) return handleError(err);
    else if (userBooks.length > 0) {
      bookList.push(userBooks);
      callback();
    }
  });
};

router.get('/', ensureAuthenticated, function(req, res, next) {
 getBookList(Book, req, function(){
      res.locals.user.books = bookList[0];
      res.render('index', { title: 'library' });
  });
});

In my jade file the code is:

ul
    each book in user.books
        li #{book.bookTitle}
            span  -  
            span #{book.author}

The first time I log in with a user I get the list as expected, but if I add a document to the db and render the page again, the list on my page doesn't update and stays as it was. Even after a logout and another login it stays the same. Only after restarting the server the list will update. can anyone explain to me what I'm doing wrong?


Solution

  • For each call to getBookList, you are pushing the resulting array of books into another array, bookList.

    So say that you have one document in the database and call getBookList. Afterwards, bookList will look something like this:

    bookList = [ [ 'book 1' ] ]
    

    Then you add another book, and call getBookList again. Now bookList looks like this:

    bookList = [ [ 'book 1' ], [ 'book 1', 'book 2' ] ]
    

    However, you are only ever using bookList[0], so the result of the first call to getBookList. This will never contain new documents, because those will only appear in later entries to bookList.

    That's not the biggest problem to solve though, because you're using bookList as a global variable, which isn't a good idea. Instead, getBookList should pass the list of books back to the caller.

    That would make the code look something like this:

    function getBookList(username, callback){
      Book.find({'username': username}, 'bookTitle author', function(err, userBooks) {
        callback(err, userBooks);
      });
    };
    
    router.get('/', ensureAuthenticated, function(req, res, next) {
     getBookList(req.user.username, function(err, userBooks) { 
      if (err) return handleError(err);
      else if (userBooks.length > 0) {
        res.locals.user.books = userBooks;
        res.render('index', { title: 'library' });
      } else {
        // handle the situation where no books were found
        ...
      }
    });
    

    There are also some other changes, like decoupling getBookList from the model (Book) and the request (req).