이 게시물에는 코드작성이 포함되어 있습니다. 소스코드를 받으신 후 진행해 주세요. MEAN Stack/개발 환경 구축에서 설명된 프로그램들(git, npm, atom editor)이 있어야 아래의 명령어들을 실행할 수 있습니다.
이 게시물의 소스코드는 게시판 만들기 / 게시판 - Login 기능 추가에서 이어집니다.
board.git 을 clone 한 적이 있는 경우: 터미널에서 해당 폴더로 이동 후 아래 명령어들을 붙여넣기합니다. 폴더 내 모든 코드가 이 게시물의 코드로 교체됩니다. 이를 원치 않으시면 이 방법을 선택하지 마세요.
board.git 을 clone 한 적이 없는 경우: 터미널에서 코드를 다운 받을 폴더로 이동한 후 아래 명령어들을 붙여넣기하여 board.git 을 clone 합니다.
- Github에서 소스코드 보기: https://github.com/a-mean-blogger/board/tree/05033c3f5f54f5ce2bb403242c157781d233ae5d
게시판 - User Error 처리에서처럼 post의 error를 처리해 봅시다.
또한 routes/user.js 에서 사용했던 parseError
함수를 post에도 그대로 사용할텐데, 이처럼 여러 파일에서 사용하게 될 함수들을 하나의 module로 분리하겠습니다.
// util.js var util = {}; util.parseError = function(errors){ var parsed = {}; if(errors.name == 'ValidationError'){ for(var name in errors.errors){ var validationError = errors.errors[name]; parsed[name] = { message:validationError.message }; } } else if(errors.code == '11000' && errors.errmsg.indexOf('username') > 0) { parsed.username = { message:'This username already exists!' }; } else { parsed.unhandled = JSON.stringify(errors); } return parsed; } module.exports = util;
원래 routes/users.js에 있던 parseError
함수를 module로 만들어 util.js 파일로 분리했습니다. 이처럼 여러 곳에서 공통으로 쓰게 될 함수들은 앞으로 util.js파일에 기록합니다
// routes/users.js var express = require('express'); var router = express.Router(); var User = require('../models/User'); var util = require('../util'); // 1 ... // create router.post('/', function(req, res){ User.create(req.body, function(err, user){ if(err){ req.flash('user', req.body); req.flash('errors', util.parseError(err)); // 1 return res.redirect('/users/new'); } res.redirect('/users'); }); }); ... // update router.put('/:username', function(req, res, next){ User.findOne({username:req.params.username}) .select('password') .exec(function(err, user){ if(err) return res.json(err); // update user object ... // save updated user user.save(function(err, user){ if(err){ req.flash('user', req.body); req.flash('errors', util.parseError(err)); return res.redirect('/users/'+req.params.username+'/edit'); // 1 } res.redirect('/users/'+user.username); }); }); }); ...
1. util
이 require
됬고, 기존에parseError
가 util.parseError
로 바뀌었습니다.
// model/Post.js var mongoose = require('mongoose'); // schema var postSchema = mongoose.Schema({ title:{type:String, required:[true,'Title is required!']}, // 1 body:{type:String, required:[true,'Body is required!']}, // 1 createdAt:{type:Date, default:Date.now}, updatedAt:{type:Date}, }); // model & export var Post = mongoose.model('post', postSchema); module.exports = Post;
1. post schema의 커스텀 에러메세지들이 추가되었습니다.
// routes/posts.js var express = require('express'); var router = express.Router(); var Post = require('../models/Post'); var util = require('../util'); // 1 ... // New router.get('/new', function(req, res){ var post = req.flash('post')[0] || {}; var errors = req.flash('errors')[0] || {}; res.render('posts/new', { post:post, errors:errors }); }); // create router.post('/', function(req, res){ Post.create(req.body, function(err, post){ if(err){ req.flash('post', req.body); req.flash('errors', util.parseError(err)); return res.redirect('/posts/new'); } res.redirect('/posts'); }); }); ... // edit router.get('/:id/edit', function(req, res){ var post = req.flash('post')[0]; var errors = req.flash('errors')[0] || {}; if(!post){ Post.findOne({_id:req.params.id}, function(err, post){ if(err) return res.json(err); res.render('posts/edit', { post:post, errors:errors }); }); } else { post._id = req.params.id; res.render('posts/edit', { post:post, errors:errors }); } }); // update router.put('/:id', function(req, res){ req.body.updatedAt = Date.now(); Post.findOneAndUpdate({_id:req.params.id}, req.body, {runValidators:true}, function(err, post){ if(err){ req.flash('post', req.body); req.flash('errors', util.parseError(err)); return res.redirect('/posts/'+req.params.id+'/edit'); } res.redirect('/posts/'+req.params.id); }); }); ... module.exports = router;
게시판 - User Error 처리에서 변경된 것과 동일하게 변경되었습니다. 상세한 설명은 생략합니다.
한가지 눈여겨 볼 점은 update의 Post.findOneAndUpdate
에 {runValidators:true}
이 추가된 것인데요, findOneAndUpdate
는 기본설정이 schema에 있는 validation을 작동하지 않도록 되어 있기때문에 이 option을 통해서 validation이 작동하도록 설정해 주어야 합니다.
ejs 역시 게시판 - User Error 처리와 동일하게 변경되었기 때문에 설명은 생략합니다.
<!-- views/posts/edit.ejs --> ... <form action="/posts/<%= post._id %>?_method=put" method="post"> <div class="form-group"> <label for="title">Title</label> <input type="text" id="title" name="title" value="<%= post.title %>" class="form-control <%= (errors.title)?'is-invalid':'' %>"> <% if(errors.title){ %> <span class="invalid-feedback"><%= errors.title.message %></span> <% } %> </div> <div class="form-group"> <label for="body">Body</label> <textarea id="body" name="body" rows="5" class="form-control <%= (errors.body)?'is-invalid':'' %>"><%= post.body %></textarea> <% if(errors.body){ %> <span class="invalid-feedback"><%= errors.body.message %></span> <% } %> </div> <% if(errors.unhandled){ %> <div class="invalid-feedback b-block"> <%= errors.unhandled %> </div> <% } %> <div> <a class="btn btn-primary" href="/posts">Back</a> <button type="submit" class="btn btn-primary">Submit</button> </div> </form> ...
<!-- views/posts/new.ejs --> ... <form action="/posts" method="post"> <div class="form-group"> <label for="title">Title</label> <input type="text" id="title" name="title" value="<%= post.title %>" class="form-control <%= (errors.title)?'is-invalid':'' %>"> <% if(errors.title){ %> <span class="invalid-feedback"><%= errors.title.message %></span> <% } %> </div> <div class="form-group"> <label for="body">Body</label> <textarea id="body" name="body" rows="5" class="form-control <%= (errors.body)?'is-invalid':'' %>"><%= post.body %></textarea> <% if(errors.body){ %> <span class="invalid-feedback"><%= errors.body.message %></span> <% } %> </div> <% if(errors.unhandled){ %> <div class="invalid-feedback d-block"> <%= errors.unhandled %> </div> <% } %> <div> <a class="btn btn-primary" href="/posts">Back</a> <button type="submit" class="btn btn-primary">Submit</button> </div> </form> ...
이번 강의는 error 처리의 복습편이였고, 다음강의에는 다시 새로운 내용을 배워보겠습니다!
댓글
이 글에 댓글을 다시려면 SNS 계정으로 로그인하세요. 자세히 알아보기