Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions api/models/books.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const mongoose = require("mongoose");

const schema = new mongoose.Schema(
{
title: { type: String, required: true },
published: { type: Number, required: true },
authors: [
{
name: { type: String },
dob: { type: Date }
}
]
},
{
timestamps: { createdAt: "created_at", updatedAt: "updated_at" }
}
);

module.exports = mongoose.model("Books", schema);
47 changes: 47 additions & 0 deletions api/routes/books.authors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const router = require("express").Router({ mergeParams: true });
const Books = require("../models/books");

//gets the authors object for a given book id
router.get("/", async (req, res, next) => {
const status = 200;
const { authors } = await Books.findById(req.params.bookId).select("authors");
res.json({ status, authors });
});

//gets the author name and dob for a given author id
router.get("/:authorId", async (req, res, next) => {
const status = 200;
const { authors } = await Books.findById(req.params.bookId).select("authors");
const author = authors.id(req.params.id);
res.json({ status, author });
});

//post (create) authors for a given book id
router.post("/", async (req, res, next) => {
const status = 201;
const book = await Books.findById(req.params.bookId).select(
"title published authors"
);
book.authors.push(req.body);
await book.save();
res.json({ status, book });
});

//updates a book document with author object for a given author id
router.put("/:authorId", async (req, res, next) => {
const status = 200;
const book = await Books.findById(req.params.bookId);
const author = book.author.id(req.params.id);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should match authorId

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be book.authors.id

Object.assign(author, req.body);
await book.save();
res.json({ status, author });
});

//delete author for a given author id
router.delete("/:authorId", async (req, res, next) => {
const status = 200;
const book = await Books.findById(req.params.bookId);
const author = book.authors.id(req.params.id).remove();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

params should match what you use in the route. so
req.params.authorId

await book.save();
res.json({ status, author });
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You must export the router at the bottom of this page :
module.exports = router;

103 changes: 53 additions & 50 deletions api/routes/books.js
Original file line number Diff line number Diff line change
@@ -1,73 +1,76 @@
const router = require('express').Router()
const { generate: generateId } = require('shortid')
const router = require("express").Router();
const { generate: generateId } = require("shortid");
const Books = require("../models/books");

const books = [
{
id: 'j9U3iNIQi',
title: 'The Colour of Magic',
id: "j9U3iNIQi",
title: "The Colour of Magic",
published: 1983,
authors: [
{
name: 'Sir Terry Pratchett',
dob: '04-28-1948'
name: "Sir Terry Pratchett",
dob: "04-28-1948"
}
]
},
{
id: 'ubQnXOfJV',
title: 'Stardust',
id: "ubQnXOfJV",
title: "Stardust",
published: 1997,
authors: [
{
name: 'Neil Gaiman',
dob: '11-10-1960'
name: "Neil Gaiman",
dob: "11-10-1960"
}
]
}
];

router.get('/', (req, res, next) => {
const status = 200
const response = books

res.json({ status, response })
})
//gets all the books
router.get("/", async (req, res, next) => {
const status = 200;
const response = await Books.find().select("-__v");
res.json({ status, response });
});

router.post('/', (req, res, next) => {
const status = 201

books.push({ id: generateId(), ...req.body })
const response = books

res.json({ status, response })
})

router.get('/:id', (req, res, next) => {
const status = 200
const response = books.find(({ id }) => id === req.params.id)

res.json({ status, response })
})

router.put('/:id', (req, res, next) => {
const status = 200
const response = { id: req.params.id, ...req.body }
const single = books.find(({ id }) => id === req.params.id)
const index = books.indexOf(single)

books.splice(index, 1, response)

res.json({ status, response })
})
//creates book document
router.post("/", async (req, res, next) => {
const status = 201;
try {
const response = await Books.create(req.body);
res.json({ status, response });
} catch (error) {
console.error(error);
const e = new Error("Something went bad");
e.status = 400;
next(e);
}
});

router.delete('/:id', (req, res, next) => {
const status = 200
const response = books.find(({ id }) => id === req.params.id)
const index = books.indexOf(response)
//gets a book document with given id
router.get("/:id", async (req, res, next) => {
const status = 200;
const response = await Books.findById(req.params.id);
res.json({ status, response });
});

books.splice(index, 1)
//updates a book document with given id
router.put("/:id", async (req, res, next) => {
const status = 200;
const response = await Books.findOneAndUpdate(
{ _id: req.params.id },
{ title: req.body.title },
{ new: true }
);
res.json({ status, response });
});

res.json({ status, response })
})
//deletes a book document with given id
router.delete("/:id", async (req, res, next) => {
const status = 200;
const response = await Books.findOneAndDelete({ _id: req.params.id });
res.json({ status, response });
});

module.exports = router
module.exports = router;
44 changes: 24 additions & 20 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
const { MONGO_DB_CONNECTION, NODE_ENV, PORT } = process.env
const express = require('express')
const mongoose = require('mongoose')
const app = express()
const { MONGO_DB_CONNECTION, NODE_ENV, PORT } = process.env;
const express = require("express");
const mongoose = require("mongoose");
const app = express();

// Database Connection
if (MONGO_DB_CONNECTION) {
mongoose.connect(MONGO_DB_CONNECTION, { useNewUrlParser: true })
console.log('Connected to database...')
mongoose.connect(MONGO_DB_CONNECTION, {
useNewUrlParser: true,
useFindAndModify: false
});
console.log("Connected to database...");
} else {
console.log('Could not connect to database!')
console.log("Could not connect to database!");
}

// Application-level Middleware
if (NODE_ENV === 'development') app.use(require('morgan')('dev'))
app.use(require('body-parser').json())
if (NODE_ENV === "development") app.use(require("morgan")("dev"));
app.use(require("body-parser").json());

// Routes
app.use('/api/books', require('./api/routes/books'))
app.use("/api/books", require("./api/routes/books"));
app.use("api/books/bookId/authors", require("./api/routes/books.authors"));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs to be :bookId to pull out as a param

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need "/" at beginning of route.


// Not Found Handler
app.use((req, res, next) => {
const error = new Error(`Could not ${req.method} ${req.path}`)
error.status = 404
next(error)
})
const error = new Error(`Could not ${req.method} ${req.path}`);
error.status = 404;
next(error);
});

// Error Handler
app.use((err, req, res, next) => {
if (NODE_ENV === 'development') console.error(err)
const { message, status } = err
res.status(status).json({ status, message })
})
if (NODE_ENV === "development") console.error(err);
const { message, status } = err;
res.status(status).json({ status, message });
});

// Open Connection
const listener = () => console.log(`Listening on Port ${PORT}!`)
app.listen(PORT, listener)
const listener = () => console.log(`Listening on Port ${PORT}!`);
app.listen(PORT, listener);