I have just a simple API I am building for school. There is a collection of Books that are being accessed, displaying book by id, displaying all books, adding book, updating book. I changed some of my code to incorporate middleware. Without middleware I am able to retrieve book by id, but when I use middleware I get an error stating book is not defined.
App.js
const express = require('express');
const bookRouter = express.Router();
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const Book = require('./models/bookModel');
const app = express();
const port = process.env.PORT || 8081;
const url = 'mongodb://localhost/bookAPI';
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
mongoose.connect(url).then(() => console.log("Connected to db"));
bookRouter.route('/books')
.post((req, res) => {
const book = new Book(req.body);
book.save();
return res.status(201).json(book);
})
.get((req, res) => {
const query = {}
if(req.query.genre) {
query.genre = req.query.genre;
}
Book.find((err, books) => {
if(err) {
return res.send(err);
}
return res.json(books);
});
});
bookRouter.use('/books/:bookId', (req, res, next) => {
Book.findById(req.params.bookId, (err, book) => {
if(err) {
return res.send(err);
}
if(book) {
req.book = book;
return next();
}
return res.sendStatus(404);
});
});
bookRouter.route('/books/:bookId')
.put((req, res) => {
const { book } = req;
book.title = req.body.title;
book.author = req.body.author;
book.genre = req.body.genre;
book.read = req.body.read;
book.save();
return res.json(book);
})
.get((req, res) => {
res.json(book);
});
app.use('/api', bookRouter);
app.get('/', (req, res) => {
res.send("Hello World");
});
app.listen(port, () => {
console.log(`Listening on port: ${port}`);
});
bookModel.js
const mongoose = require('mongoose');
const {Schema} = mongoose;
const bookModel = new Schema({
title: {type:String},
author: {type:String},
genre: {type:String},
read: {type:Boolean, default: false},
});
module.exports = mongoose.model("Book", bookModel);
Error when I request get by book id:
ReferenceError: book is not defined
at D:\Desktop\lab10\app.js:63:14
at Layer.handle [as handle_request] (D:\Desktop\lab10\node_modules\express\lib\router\layer.js:95:5)
at next (D:\Desktop\lab10\node_modules\express\lib\router\route.js:137:13)
at next (D:\Desktop\lab10\node_modules\express\lib\router\route.js:131:14)
at Route.dispatch (D:\Desktop\lab10\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (D:\Desktop\lab10\node_modules\express\lib\router\layer.js:95:5)
at D:\Desktop\lab10\node_modules\express\lib\router\index.js:281:22
at param (D:\Desktop\lab10\node_modules\express\lib\router\index.js:360:14)
at param (D:\Desktop\lab10\node_modules\express\lib\router\index.js:371:14)
at Function.process_params (D:\Desktop\lab10\node_modules\express\lib\router\index.js:416:3)
CodePudding user response:
Your error comes from this code:
.get((req, res) => {
res.json(book);
});
Here you're trying to send book
, but in this callback, book
is out of it's scope. You can try to declare it in a higher scope or return it somehow in upper scopes
CodePudding user response:
@Molda found the error. I should be passing req.book in my response, and not book.
Correct code
.get((req, res) => {
res.json(req.book);
});