# 수정 폼(form) 데이터 주고 받기
## 미션
---
상세 페이지에서 수정 버튼을 클릭하여 수정 페이지가 나오게 하고,
![클라우드스터딩-스프링부트-수정-버튼-클릭](https://i.imgur.com/CRWL85l.png)
수정한 내용을 서버로 전달하시오. Ajax 사용 할 것.
![클라우드스터딩-스프링부트-ajax-데이터-전송][Imgur](https://i.imgur.com/CUcuKsL.png)
## 개념
---
#### ⭐️ 진행흐름
먼저, 버튼을 클릭하면 데이터 수정 폼을 보여준다.
![클라우드스터딩-스프링-부트-데이터-수정하기](https://i.imgur.com/ak0VX5g.png)
다음으로, 데이터를 변경 및 제출. 이를 서버에서 확인.
![클라우드스터딩-스프링-부트-데이터-수정하기](https://i.imgur.com/1nNZeV2.png)
## 튜토리얼
---
#### ⭐️ 추가 파일
![클라우드스터딩-스프링부트-데이터-수정-구조](https://i.imgur.com/KKAxfYs.png)
#### ⭐️ 뷰 페이지
1) 수정 페이지 생성: "articles/edit.mustache"
```
{{>layouts/header}}
<div class="jumbotron">
<h1>Article 수정</h1>
<hr>
<p>articles/edit.mustache</p>
</div>
<form class="container">
{{#article}}
<div class="form-group">
<label for="title">제목</label>
<!-- value 속성 추가 -->
<input name="title" type="text" class="form-control" id="article-title" placeholder="제목을 입력하세요" value="{{title}}">
</div>
<div class="form-group">
<label for="content">내용</label>
<!-- textarea 내부 텍스트 추가 -->
<textarea name="content"class="form-control" id="article-content" placeholder="내용을 입력하세요" rows="3">{{content}}</textarea>
</div>
<!-- 숨겨진 입력값 id 추가 -->
<input type="hidden" id="article-id" value="{{id}}">
<button type="button" class="btn btn-primary" id="article-update-btn">제출</button>
{{/article}}
</form>
<Script>
// 데이터 전송 객체 생성!
var article = {
// 초기화(이벤트 등록) 메소드
init: function() {
// 스코프 충돌 방지! (https://mobicon.tistory.com/189)
var _this = this;
// 생성 버튼 선택
const updateBtn = document.querySelector('#article-update-btn');
// 생성 버튼 클릭 시, 동작 할 메소드를 연결!
updateBtn.addEventListener('click', _this.update);
},
// article 갱 메소드
update: function() {
// form 데이터를 JSON으로 만듬
var data = {
id: document.querySelector('#article-id').value,
title: document.querySelector('#article-title').value,
content: document.querySelector('#article-content').value,
};
// 데이터 갱신 요청을 보냄
// fetch(URL, HTTP_REQUEST)
fetch('/api/articles/' + data.id, {
method: 'PUT', // PUT 방식으로, HTTP 요청.
body: JSON.stringify(data), // 위에서 만든 폼 데이터(data)를 함께 보냄.
headers: {
'Content-Type': 'application/json'
}
}).then(function(response) { // 응답 처리!
// 요청 성공!
if (response.ok) {
alert('게시글이 작성 되었습니다.');
window.location.href='/articles/' + data.id; // 해당 URL로 브라우저를 새로고침!
} else { // 요청 실패..
alert('게시글 작성에 문제가 생겼습니다.');
}
});
}
};
// 객체 초기화!
article.init();
</script>
{{>layouts/footer}}
```
2) 수정 버튼 추가: "articles/show.mustache"
```
...
<!-- table -->
<table class="table table-hover">
...
</tbody>
<!-- 수정 버튼 추가 -->
<tfoot>
<tr>
<th></th>
<td><a class="btn btn-info" href="/articles/edit/{{id}}">수정</a></td>
</tr>
</tfoot>
</table>
...
```
#### ⭐️ 일반 컨트롤러
3) 수정 페이지 보여주기: "controller/ArticleController"
```
...
public class ArticleController {
...
@GetMapping("/articles/edit/{id}")
public String edit(@PathVariable Long id,
Model model) {
Article target = articleRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("해당 Article이 없습니다.")
);
model.addAttribute("article", target);
return "articles/edit";
}
}
```
#### ⭐️ API 컨트롤러
4) 데이터 받기: "api/ArticleAPIController"
```
...
@Slf4j
@RestController
public class ArticleApiController {
...
@PutMapping("/api/articles/{id}") // HTTP 메소드 PUT으로 "/api/articles/{id}" 요청이 들어오면 수행!
public Long update(@PathVariable Long id,
@RequestBody ArticleForm form) {
log.info("form: " + form.toString()); // 받아온 데이터 확인!
return 0L;
}
}
```
#### ⭐️ 확인하기
5) 버튼 클릭
![클라우드스터딩-스프링부트-수정-버튼-클릭](https://i.imgur.com/CRWL85l.png)
6) 데이터 수정 및 전송
![클라우드스터딩-스프링부트-데이터-수정-시-에러-발생](https://i.imgur.com/TA8Zp4X.png)
## 훈련하기
---
- 위 에러의 원인을 찾고, 이를 해결하시오. (힌트: "@NoArgsConstrouctor")
![클라우드스터딩-스프링부트-ajax-데이터-전송][Imgur](https://i.imgur.com/CUcuKsL.png)
## 면접 준비
---
- form 데이터 전송 vs Ajax 데이터 전송 차이?
- Ajax는 왜 사용?