문제상황
모달을 열 때, member 정보를 보내줘서 신분증 이미지를 내려주는 api가 연동되어있던 부분에서 오류가 났다.
기존 다른 api의 경우, 이미지의 url을 response로 내려주었는데 해당 api는이미지 그 자체
를 내려주었다.
스웨거로 요청할 때는 정상적으로 이미지가 나오는데
흠?
삽질1
내려온 이미지를 blob 객체로 변환해서 imageUrl을 생성해보았다. → url을 만드는 과정에서 blob url이 달라졌다.
const imageUrl = window.URL.createObjectURL(new Blob([response.data]));
- 스웨거에서는 image url이
blob:https://{link}/{memberId}
이렇게 나오는데, 로컬에서 테스트할때는 다르게 나왔다.
삽질2
- response type을
arraybuffer
로 설정했다.
getImage: (params: GetImageParams) => {
return requester.get<GetImageResponse>(
`${BASE_URL}/image`,
{
params,
responseType: 'arraybuffer',
},
);
},
- 그런데 api를 호출하는 쪽에서 blob객체를 url로 변환하려고 하니까 자꾸 타입 안맞다고 에러가 떴다.
원인
이미지 생성하는데 시간이 좀 걸렸는데 생성 전까지는 이미지가 undefined
이기 때문에 api 호출하는 쪽에서 처음에 undefined로 뜨는걸 계속 변환하려고 하니까 에러가 떴던 거였다.
해결
api hook 안에서 async await
걸고 안에서 변환해서 변환한 url link를 return해주니까 해결!
const useGetImage = (params: GetImageParams) => {
return useQuery(
queryKey,
async () =>
await Api.getImage(params).then((response) => {
const blob = new Blob([response.data], { type: "image/png" })
const imageUrl = URL.createObjectURL(blob)
return imageUrl
})
)
}
리팩토링
const useGetImage = (params: Partial<GetImageParams>, enabled?: boolean) => {
return useQuery(
queryKey,
async () => {
const response = await Api.getImage(params)
const blob = new Blob([response.data], { type: "image/png" })
const imageUrl = URL.createObjectURL(blob)
return imageUrl
},
{
enabled: enabled ?? !!(params.fileName && params.key),
onError: async (error: AxiosError<any>) => {
snackbar.error({
title: "이미지 불러오기 실패",
content:
JSON.parse(await error?.response?.data?.text()).status.message ||
"이미지를 불러오지 못했습니다.",
})
},
}
)
}