- 기본적으로 사용자가 요청을 보낼 때 HTML 페이지를 다시 렌더링 할 수 도있지만, JSON 형태로 response로 보내 줄 수도 있습니다.
- 이 방법은 기존에 HTML response로 보내주는 방식보다 더 빠른 속도로 통신할 수 있습니다.
- Client JavaScript를 활용해 DOM 객체를 업데이트 하는 방법을 사용해 봅시다.
-
views/admin/products.ejs
-
JavaScript 를 적용하기 위해 public/js/admin.js만들고 import하기
<script src="/js/admin.js"></script>
-
기존 form 형태로 서버에 request 보내는 대신 Client JavaScript 이용해서 request 데이터 가져오기 기존 코드
<div class="card__actions"> <a href="/admin/edit-product/<%= product._id %>?edit=true" class="btn">Edit</a> <form action="/admin/delete-product" method="POST"> <input type="hidden" value="<%= product._id %>" name="productId"> <input type="hidden" name="_csrf" value="<%= csrfToken %>" /> <button class="btn" type="submit">Delete</button> </form> </div>
변경된 코드
<div class="card__actions"> <a href="/admin/edit-product/<%= product._id %>?edit=true" class="btn">Edit</a> <input type="hidden" value="<%= product._id %>" name="productId"> <input type="hidden" name="_csrf" value="<%= csrfToken %>" /> <button class="btn" type="button" onclick="deleteProduct(this)">Delete</button> </div>
-
-
public/js/admin.js
-
버튼을 클릭해서 정보 브라우저에서 데이터 가져오기
const deleteProduct = btn => { // <button class="btn" type="button" onclick="deleteProduct(this)">Delete</button> console.log(btn); // productId 가져오는 방법 // <input type="hidden" value="{productId}" name="productId"> console.log(btn.parentNode.querySelector('[name=productId]')); };
-
vlaue 값 가져오기
const deleteProduct = btn => { const prodId = btn.parentNode.querySelector('[name=productId]').value; const csrf = btn.parentNode.querySelector('[name=_csrf]').value; };
-
-
routes/admin.js
-
기존
postDeleteProduct라우터에서 post 요청을 delete 요청으로 바꾸기// productId 를 params로 보낸다. router.delete('/product/:productId', isAuth, adminController.deleteProduct);
-
-
controllers/admin.js
-
postDeleteProduct>deleteProduct로 수정하기exports.deleteProduct = (req, res, next) => { // form 요청으로 보내는 것이 아니라 url에서 받음으로 const prodId = req.params.productId; Product.findById(prodId) .then(product => { if (!product) { return next(new Error('Product not Found.')); } fileHelper.deleteFile(product.imageUrl); return Product.deleteOne({ _id: prodId, userId: req.user._id }); }) .then(result => { console.log(result); console.log('DESTROYED PRODUCT'); // status 코드를 보내주고 json으로 보내줄 데이터를 JavaScript 객체로 보내주면 // 자동으로 json 형식으로 변환해줌 res.status(200).json({ message: 'Success!' }); }) .catch(err => { res.status(500).json({ message: 'Error' }); }); };
-
-
public/js/admin.js
-
fetch() 함수 사용하기
const deleteProduct = btn => { const prodId = btn.parentNode.querySelector('[name=productId]').value; const csrf = btn.parentNode.querySelector('[name=_csrf]').value; // fetch 함수를 통해 서버에 request를 보낸다 // 이 요청은 admin의 deleteProduct 라우터로 전달된다. fetch('/admin/product/' + prodId, { method: 'DELETE', headers: { 'csrf-token': csrf } }) .then(result => { console.log(result); }) .catch(err => { console.log(err); }); };
-
우리가 delete 버튼을 누르면 데이터베이스에서 해당 product가 삭제되는 것을 보았습니다. 이어서 이 요청에 의해 DOM에서도 product가 삭제 되도록 해보겠습니다
-
public/js/admin.js
const deleteProduct = btn => { const prodId = btn.parentNode.querySelector('[name=productId]').value; const csrf = btn.parentNode.querySelector('[name=_csrf]').value; // closet() 가장 가까운 element를 찾아줌 const productElement = btn.closest('article'); fetch('/admin/product/' + prodId, { method: 'DELETE', headers: { 'csrf-token': csrf } }) .then(result => { return result.json(); }) .then(data => { console.log(data); // 해당 child DOM을 삭제 productElement.parentNode.removeChild(productElement); }) .catch(err => { console.log(err); }); };
이 방법은 페이지가 reload 되는 것이 아니라 Client Side 자바스크립트에 의해서 페이지가 변경되는 것입니다.
