티스토리 뷰

좋아요 버튼기능 구현

저번시간에 api는 완성하였고 이제 버튼에 적용시킬려한다 그럼 버튼을 찾아와서 거기에맞게 알맞은 요청을 보내면 될거같다 바로 만들어보자.

// (3) 좋아요, 안좋아요
function toggleLike(imageId) {
	let likeIcon = $(`#storyLikeIcon-${imageId}`);
	if (likeIcon.hasClass("far")) { // 좋아요 하겠다
		$.ajax({
			type:"post",
			url:`/api/image/${imageId}/likes`,
			dataType:"json"
		}).done(res=>{
			let likeCountStr = $(`#storyLikeCount-${imageId}`).text();
			let likeCount = Number(likeCountStr) +1;
			$(`#storyLikeCount-${imageId}`).text(likeCount)
			
			likeIcon.addClass("fas");
			likeIcon.addClass("active");
			likeIcon.removeClass("far");
		}).fail(err=>{
			console.log("오류",err)
		})
	} else { // 좋아요 취소
				$.ajax({
			type:"delete",
			url:`/api/image/${imageId}/likes`,
			dataType:"json"
		}).done(res=>{
			let likeCountStr = $(`#storyLikeCount-${imageId}`).text();
			let likeCount = Number(likeCountStr) -1;
			$(`#storyLikeCount-${imageId}`).text(likeCount)
			
			likeIcon.removeClass("fas");
			likeIcon.removeClass("active");
			likeIcon.addClass("far");
		}).fail(err=>{
			console.log("오류",err)
		})
	
	}
}

요청

far라는건 빈하트라는 뜻이다 즉 좋아요를 하겠다이고

fas는 빨간하트니까 좋아요를 취소하겠다는뜻으로 의미된다.

그럼 거기에 맞게 같은요청인데 type만 바꿔 요청을 다르게 한다면 좋아요와 취소가 구현될거같다.

 

숫자표기

요청은 완료되었고 이제 눌렀을때 숫자도 변하게 하고싶다면 해당 태그를 들고와 그태그안의 text에 내가 원하는 값을 넣어주면 된다 그럼 어떻게 해야할까?

기존의 text를 가져오고 요청을 완료한뒤 +1이나 -1을 해주면 되는것이다

하지만 String와 int를 더하면 붙여쓰기가 된다 예를들어 기존의 숫자가(String) 11 이 있고 여기에 +1 을하게되면 111이란 문자가 나온다 이를 방지하기위해서 Number로 정수화시켜 연산하고 text안에 기입해주자.

 

무한참조 버그 해결

현제 태이블은 user,likes,subscribe,images가 존재한다

테이블을 삭제할때 부모와 자식관계에서는 자식을 먼저 삭제하고 부모를 삭제해야 오류가 안난다

예를 들어 현재 태이블로 예시를 들어보면

likes테이블의 참조 상태는

public class Likes { // N

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY) 
	private int id;
	
	// 무한 참조됨
	@JoinColumn(name="imageId")
	@ManyToOne
	private Image image; // 1
	
	@JsonIgnoreProperties({"images"})
	@JoinColumn(name="userId")
	@ManyToOne
	private User user; // 1
	
	private LocalDateTime createDate;

Image의 imageId를 참조하고 또 User의 userId를 참조하고있다

그렇다는건 User와 image를 참조여 만들어진 테이블이 Likes테이블이다

이테이블을 삭제할땐 문제가없지만 부모인 User와 Image를 drop할려하면 자식이 참조하고있다고 에러가 나게된다.

 

스토리게시물의 데이터와 dmain의 클래스를 보면 

likes의 맴버필드                                                                                                 User의 맴버필드

image맴버필드 ( User맴버필드중 images)

images의 likes에는 좋아요 한사람의 데이터가 담기는데

현재의 상태에서 1번이미지에 likes에데이터가 쌓이는 순간 무한참조가 발생하게된다 2번의 아이디로 1번게시물을 좋아요 해보겠다.

 

 

 

 

 

 

 

 

 

무한참조의 결과는 이러하다.

계속 images가 참조를 계속하며 끝없이 무한참조에 빠지게되었다 

그럼 어떻게 해석해야할까 likes클래스에 user멤버필드에서 images참조할때 무한참조가 발생되고있다고 인식하면된다

그럼 코드를 이렇게 설정해주면 해결이된다 

public class Likes { // N

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY) 
	private int id;

	@JoinColumn(name="imageId")
	@ManyToOne
	private Image image; // 1
	
	@JsonIgnoreProperties({"images"})
	@JoinColumn(name="userId")
	@ManyToOne
	private User user; // 1
	private LocalDateTime createDate;
}

위와같이 설정을 완료하고 다시 postman으로 요청을 하게되면

위와같은 결과물이 보일것이다 likes에 user맴버의 images가 사라진모습이다.

 

콘솔에서 에러를 보는방법

다시 @JsonIgnoreProperties({"images"}) 지우고 에러를 이클립스 콘솔창에 출력해보게된다면

 

위와같이 에러코드 중간지점쯤 보면 길게 에러가 발생하였을것이다.

위 에러코드 한줄을 코드블럭에 풀어서 표현하면 밑과 같은데 생략해서 이정도이다

2023-06-14 15:48:34.874 ERROR 22264 --- 
[nio-8080-exec-6] o.a.c.c.C.[.[.[/].[dispatcherServlet]   
 : Servlet.service() for servlet [dispatcherServlet] in context with path 
[] threw exception [Request processing failed; nested exception is org.springframework.http.
converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion 
(StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException:
Infinite recursion (StackOverflowError) (through reference chain: org.hibernate.collection
.internal.PersistentBag[0]->com.cos.photogramstart.domain.image.Image["likes"]->org.hibernate
.collection.internal.PersistentBag[0]->com.cos.photogramstart.domain.likes.Likes["user"]->
om.cos.photogramstart.domain.user.User["images"]->org.hibernate.collection.internal.Persist
entBag[0]->com.cos.photogramstart.domain.image.Image["likes"]->org.hibernate.collection.inte
rnal.PersistentBag[0]->com.cos.photogramstart.domain.likes.Likes["user"]->com.cos.photogramsta
rt.domain.user.User["images"]->org.hibernate.collection.internal.PersistentBag[0]->com.cos.pho

보면은 likes에서 user를참조하고user에서 images를 참조하고 likes - user - images 라고 길게 늘어져서 나온다 이말은 

현재 likes클래스의 user맴버의 images를 계속참고하고있다는 말이된다 그렇다면 중간에있는 likes클래스의 user에

@JsonIgnoreProperties({"images"}) 를 걸어주면 되지않을까? 정답이다 그렇게 생각하는게 도움이 될것이다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함