실습

API 명세서

  • todo.js
//초기데이터 (나중에는 서버에서 받아올 부분)

let basicDatas = [];

function getTodos(){
    const xhr = new XMLHttpRequest();
    xhr.open("get","http://localhost:8080/api/todos");
    xhr.onreadystatechange = function(){
       if(xhr.readyState === 4 ){
           if(xhr.status === 200){
               // json 문자열을 json 객체로 변환시킨다.
               let todos = JSON.parse(this.responseText);
               // console.log(todos);
               for(let i = 0; i < todos.length; i++){
                   todoItemAdd(todos[i]);
               }
            }
        }
   }
   xhr.send();
}

function updateTodo(id){
//    let updateTodo = {"id":id};
    let xhr = new XMLHttpRequest();
    xhr.open('PATCH','http://localhost:8080/api/todos/'+id);
    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    // xhr.send(JSON.stringify(updateTodo));
    xhr.send();
}

function deleteTodo(id){
    let delTodo = {"id": id};  //이거 주석처리가 딜리트 위아래를 나타냄
    let xhr = new XMLHttpRequest();
//    xhr.open('DELETE','http://localhost:8080/api/todos');
    xhr.open('DELETE','http://localhost:8080/api/todos/'+id);
    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
     xhr.send(JSON.stringify());
//    xhr.send(JSON.stringify(delTodo));
}

function postTodo(todo){
    let xhr = new XMLHttpRequest();
    xhr.open('post','http://localhost:8080/api/todos');
    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    xhr.onload = function(){
        // 글쓰기를 할 경우 ajax의 결과를 json 오브젝트로 변환하여 추가한다.
        todoItemAdd(JSON.parse(xhr.responseText));
    };
    xhr.send(JSON.stringify({"todo":todo}));
}

getTodos();

let todoUl = document.querySelector("#todo-item-list");

todoUl.addEventListener('click',function(event){
    let eventTarget = event.target;
    if(event.target.tagName === 'LI' || event.target.tagName === 'SPAN'){
        if(event.target.tagName ==='LI'){
            eventTarget =eventTarget.querySelector('.todo-text');
        }

        let liObj = eventTarget.parentElement;

        updateTodo(liObj.getAttribute("id"));
        eventTarget.classList.toggle('checked');
    }
});

 const inputbtn = document.querySelector('.add-button');
//  const myinput = document.querySelector('#myInput');


inputbtn.addEventListener('click', function(){
    inputValue = document.querySelector('#myInput').value;
    if(inputValue === ''){
        alert("할 일을 입력해 주세요^^ ");
        return;
    }
    document.querySelector('#myInput').value = '';
    postTodo(inputValue);
});

function todoItemAdd(todoObj){
    console.log(todoObj);
    const li = document.createElement('li');
    li.className = "todo-item";
    const textSpan = document.createElement('SPAN');
    textSpan.className = "todo-text" ;

    const todotxt = document.createTextNode(todoObj.todo);
    textSpan.appendChild(todotxt);
    if(todoObj.done == true){
        // 완료된 작업일 경우 css를 이용하여 줄을 긋는다.
        textSpan.classList.toggle('checked');
    }
    li.appendChild(textSpan);
    li.setAttribute("id", todoObj.id);
    document.getElementById('todo-item-list').appendChild(li);

    const removeSpan = document.createElement("SPAN");
    const removetxt = document.createTextNode("\u00D7");
    removeSpan.className = "remove";

    removeSpan.appendChild(removetxt);
    li.appendChild(removeSpan);

    // 동적으로 x버튼을 클릭했을 때 처리해야할 이벤트를 추가한다.
    removeSpan.addEventListener('click',function(){
        let liObj = this.parentElement;
        console.log(liObj);
        deleteTodo(liObj.getAttribute("id"));
        liObj.remove();
        return false; // return false를 하지 않으면 수정이 되면서 update를 호출한다.이미 삭제된 것을 수정하려고 하니 오류가 발생한다. https://programmingsummaries.tistory.com/313
    });
};
  • TodoService
@Service
@RequiredArgsConstructor
public class TodoService {
    private final TodoRepository todoRepository;

    @Transactional(readOnly = true)
    public List<Todo> getTodos(){
        return todoRepository.findAll(Sort.by("id").descending());
    }

    @Transactional
    public Todo addTodo(String todo){
        return todoRepository.save(new Todo(todo));
    }

    @Transactional
    public Todo updateTodo(Long id){
        boolean exists = todoRepository.existsById(id);
        if(!exists){
            throw new EntityNotFoundException("이미 삭제된 Todo 입니다." + id);
        }
        Todo todo = todoRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("id에 해당되는  todo를 찾을 수 없어요." + id));

        todo.setDone(!todo.isDone());
        return todo;
    }

    @Transactional
    public void deleteTodo(Long id){
        if(!todoRepository.existsById(id)){
            throw new RuntimeException("id에 해당하는 todo가 없어요."+id);
        }
        todoRepository.deleteById(id);
    }

}
  • TodoRepository
public interface TodoRepository extends JpaRepository<Todo,Long> {

}
  • Todo
@Entity
@Table(name = "todos")
@Getter
@Setter
@NoArgsConstructor
@ToString
public class Todo {
    @Id@GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String todo;  // 할 일 내용
    private boolean done; // 완료 여부

    public Todo(String todo) {
        this.todo = todo;
    }
}
  • TodoController
@RestController
@RequestMapping("/api/todos")
@RequiredArgsConstructor
public class TodoController {
    private final TodoService todoService;

    @GetMapping
    public ResponseEntity<List<Todo>> getTodos(){
        return ResponseEntity.ok(todoService.getTodos());
    }

    //todo 추가
    @PostMapping
    public ResponseEntity<Todo> addTodo(@RequestBody Todo todo){
        Todo createTodo = todoService.addTodo(todo.getTodo());
        return ResponseEntity.status(HttpStatus.CREATED).body(createTodo);
    }

    //todo의 done 수정
    @PatchMapping("/{id}")
    public ResponseEntity<Todo> updateTodd(@PathVariable("id")Long id){
        Todo updateTodo = todoService.updateTodo(id);
        return ResponseEntity.ok(updateTodo);
    }
//
    @DeleteMapping
    public ResponseEntity<Void> deleteTodo2(@RequestBody Todo todo){
        todoService.deleteTodo(todo.getId());
        return ResponseEntity.noContent().build();
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteTodo(@PathVariable("id")Long id){
        todoService.deleteTodo(id);
        return ResponseEntity.noContent().build();
    }
}
  • 기존에 만든것은 done처리가 잘안되었고, 삭제를 해도 정상적으로 삭제안되는 현상(새로고침시 살아남)이 일어났으며, 54일차에서 실습한것에 대해 복습 및 되돌아보는시간을 가지면서 잘못짜여진것들에 대해 알게된 시간을 가지게되었습니다.
profile
신입개발자

0개의 댓글