혼자 고민해보기_ 개발/TIL (Today I Learned)

20230908(금)_ 최종프로젝트 진행

nuri-story 2023. 9. 8. 22:45

금일 달성 항목

1) S3 유저 이미지 등록 및 수정, 기본이미지 설정 기능 추가

2) 채용공고 생성 및 추가 기능 front 연결


문제 해결 과정 1 - 이미지 S3 등록

[문제]
이미지 등록까지는 되나 등록이 되지 않아 DB에 이전 이미지 url 값이 그대로 남아있는 상황이었습니다.

 

[시도 및 해결]

튜터님께서 s3에 등록이 되지 않는 것 같다고하셔서 코드를 다시 수정했습니다.

 

https://bin-repository.tistory.com/154

 

[nest.js] AWS s3 bucket 에 파일 여러개 업로드 + rest api 만들기

👉 postman 에서 실행해본 결과 위 사진과 같이 form-data 로 여러 파일을 첨부하고 AWS s3 bucket 에 업로드 한 후 값들을 db 에 저장하고 저장된 데이터들을 response 로 리턴해주는 기능을 만들어볼 것입

bin-repository.tistory.com

 

https://codesk.tistory.com/61

 

[바미] Nestjs 및 TypeScript를 사용하여 AWS S3에 이미지 업로드

Nestjs 및 TypeScript를 사용하여 AWS S3에 이미지 업로드 최근 프로젝트에서 백엔드에 있는 Nestjs와 Typescript를 사용하여 AWS S3에 이미지를 업로드해야 했습니다. Typescript와 Nestjs를 사용하여 이 작업을

codesk.tistory.com

이런 저런 사이트를 뒤져 맞게 수정을 했는데 

이미지 url 이 아닌 다운로드 파일로 선택시 파일이 다운로드되는 형태로 s3에 삽입되었습니다 ;

 

결론은 uplode영역은 복구 시키고

user 영역에서 image 만 수정하게 하는 api 를 생성

추가로 프론트 영역의 다시 코드를 다듬었더니 

 

user-mypage.js

async function getUserImage() {
  const userImage = document.getElementById('image');
  const imageUploadEl = document.getElementById('user-image');
  const imageDeleteEl = document.getElementById('image-delete');
  const saveBtnEl = document.getElementById('save-btn');
  let imageUrl = userImage.src; // 기존 이미지 URL 가져오기

  // 기본 프로필 적용하기
  imageDeleteEl.addEventListener('click', () => {
    imageUrl = '/img/userImg.jpg'; // 이미지 삭제 시 URL 업데이트
    userImage.src = imageUrl; // 이미지 보여주기
  });

  imageUploadEl.addEventListener('change', async (e) => {
    const selectedFile = e.target.files[0];
    console.log(selectedFile);
    // 파일 유효성 검사
    if (selectedFile) {
      if (selectedFile.size > 1 * 1024 * 1024) {
        alert('파일 용량은 최대 1MB입니다.');
        return;
      }

      if (
        !selectedFile.type.includes('jpeg') &&
        !selectedFile.type.includes('png')
      ) {
        alert('jpeg 또는 png 파일만 업로드 가능합니다!');
        return;
      }

      const formData = new FormData();
      formData.append('file', selectedFile);

      try {
        const response = await fetch('/api/upload', {
          method: 'POST',
          body: formData,
        });
        if (response.ok) {
          const data = await response.json();
          imageUrl = data.url; // 업로드된 이미지 URL 업데이트
          userImage.src = imageUrl; // 이미지 보여주기

          console.log(data);
        } else {
          throw new Error('이미지 업로드에 실패했습니다.');
        }
      } catch (error) {
        console.error(error);
        alert('이미지 업로드에 실패했습니다.');
      }
    }
  });

  saveBtnEl.addEventListener('click', async () => {
    if (imageUrl) {
      try {
        await saveUserImage(imageUrl);
        alert('이미지가 저장되었습니다.');
        window.location.reload();
      } catch (error) {
        console.error('이미지 저장 오류:', error);
        alert('이미지 저장에 실패했습니다.');
      }
    } else {
      alert('이미지를 먼저 업로드하세요.');
    }
  });

  async function saveUserImage(imageUrl) {
    try {
      const response = await fetch('/api/users/image', {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ image: imageUrl }),
      });

      if (!response.ok) {
        throw new Error('이미지 저장 실패');
      }
    } catch (error) {
      console.error('이미지 저장 오류:', error);
      throw error;
    }
  }
}

해결하였습니다.

 

프론트 코드가 잘못되었던 것 같습니다.

 

[알게된 점]

구글링을 더 연습해야겠습니다. 더 빨리 찾았으면 더 빨리 끝났을 텐데

 


문제 해결 과정 2 - 채용공고 생성

[문제]
채용공고 생성 API가 post men으로 잘되나 프론트 영역에서 자꾸만 400 에러가 떴습니다.

 

[시도 및 해결]

결론은 데이터베이스의 조건을 제대로 확인하지 못해서 였습니다;

content의 글자는 10자 이상 입력해야하고 

duedate의 값은 date로 되어있어서 string으로 변경해주었습니다.

 

jobposting.create.dto

import { IsNotEmpty, IsString, MinLength } from 'class-validator';

export class CreateJobpostingDto {
  @IsNotEmpty()
  @IsString()
  title: string;

  @IsNotEmpty()
  @IsString()
  career: string;

  @IsNotEmpty()
  @IsString()
  salary: string;

  @IsNotEmpty()
  @IsString()
  education: string;

  @IsNotEmpty()
  @IsString()
  job: string;

  @IsNotEmpty()
  @IsString()
  workType: string;

  @IsNotEmpty()
  @IsString()
  workArea: string;

  @IsNotEmpty()
  @IsString()
  @MinLength(10) //최솟값
  content: string;

  @IsNotEmpty()
  @IsString()
  dueDate: string;
}

 

 

[알게된 점]

구글링을 더 연습해야겠습니다. 더 빨리 찾았으면 더 빨리 끝났을 텐데