diff --git a/.eslintrc.json b/.eslintrc.json index de351df..5aa5c53 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,6 +8,7 @@ "allowTernary": true } ], - "no-console": "off" + "no-console": "off", + "no-underscore-dangle": ["on", { "allow": ["_id"] }] } } diff --git a/app.js b/app.js index a449837..bfe0a08 100644 --- a/app.js +++ b/app.js @@ -20,6 +20,12 @@ mongoose.connect(process.env.MONGODB_URI); require('./models/Todo'); require('./models/TodoList'); +const todos = require('./routes/todos'); +const lists = require('./routes/lists'); + +app.use('/todos', todos); +app.use('/lists', lists); + // 404 route app.use((req, res) => { res.status(404); @@ -37,6 +43,19 @@ app.use((req, res) => { res.type('txt').send('not found'); }); +// handle errors + +app.use((err, req, res, next) => { + if (err.name === 'ValidationError') { + res.status(400); + res.json({ success: false, error: err }); + } else { + res.status(500); + res.json({ success: false, error: err }); + } + next(err); +}); + app.listen(process.env.PORT, () => { console.log('Started!'); }); diff --git a/asyncHelper.js b/asyncHelper.js new file mode 100644 index 0000000..f6bcfb5 --- /dev/null +++ b/asyncHelper.js @@ -0,0 +1,3 @@ +module.exports = fn => (req, res, next) => { + Promise.resolve(fn(req, res, next)).catch(next); +}; diff --git a/models/Todo.js b/models/Todo.js index 89be0ba..4216045 100644 --- a/models/Todo.js +++ b/models/Todo.js @@ -3,13 +3,12 @@ const mongoose = require('mongoose'); const { Schema } = mongoose; const todoSchema = Schema({ - _id: Schema.Types.ObjectId, text: { type: String, required: true, }, - list: { type: Schema.Types.ObjectId, ref: 'TodoList' }, - completed: Boolean, + list: { type: Schema.Types.ObjectId, ref: 'TodoList', required: true }, + completed: { type: Boolean, default: false }, }); mongoose.model('Todo', todoSchema); diff --git a/models/TodoList.js b/models/TodoList.js index 7042505..a526bd2 100644 --- a/models/TodoList.js +++ b/models/TodoList.js @@ -3,7 +3,6 @@ const mongoose = require('mongoose'); const { Schema } = mongoose; const todoListSchema = Schema({ - _id: Schema.Types.ObjectId, name: { type: String, required: true, diff --git a/routes/lists.js b/routes/lists.js new file mode 100644 index 0000000..2603d34 --- /dev/null +++ b/routes/lists.js @@ -0,0 +1,32 @@ +const express = require("express"); +const mongoose = require("mongoose"); + +const router = express.Router(); + +const TodoList = mongoose.model("TodoList"); + +const asyncHelper = require("../asyncHelper"); + +// index +router.get( + "/", + asyncHelper(async (req, res) => { + const lists = await TodoList.find({}) + .populate("todos") + .exec(); + res.json(lists); + }) +); + +// create +router.post( + "/", + asyncHelper(async (req, res) => { + const { name } = req.body; + const newList = new TodoList({ name }); + await newList.save(); + res.json({ success: true }); + }) +); + +module.exports = router; diff --git a/routes/todos.js b/routes/todos.js new file mode 100644 index 0000000..6d9e7b2 --- /dev/null +++ b/routes/todos.js @@ -0,0 +1,34 @@ +const express = require("express"); +const mongoose = require("mongoose"); + +const router = express.Router(); + +const TodoList = mongoose.model("TodoList"); +const Todo = mongoose.model("Todo"); + +const asyncHelper = require("../asyncHelper"); + +// index +router.get( + "/", + asyncHelper(async (req, res) => { + const todos = await Todo.find({}).exec(); + res.json(todos); + }) +); + +// create +router.post( + "/", + asyncHelper(async (req, res) => { + const { text, listId } = req.body; + const list = await TodoList.findById(listId); + const todo = new Todo({ text, list: list._id }); + await todo.save(); + list.todos.push(todo.id); + await list.save(); + res.json({ success: true }); + }) +); + +module.exports = router;