• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

데코레이터의 인자로 클래스내의 프로퍼티 혹은 메서드등을 this로 전달할 수 없나요?

22.06.23 10:25 작성 조회수 76

1

 안녕하세요 조현영님. 이번에는 데코레이터에 this를 전달하려는데 this에 빨간줄에러가 나서 문의드립니다.

이미지 업로드등을 하기 위해서 아래처럼 MulterProvider라는 provider를 만들고 해당 모듈에 provider에 넣어주었습니다. 

// multer.provider.ts
import { Injectable, Logger } from "@nestjs/common";
import { MulterOptions } from "@nestjs/platform-express/multer/interfaces/multer-options.interface";

import * as fs from "fs";
import * as path from "path";
import * as multer from "multer";

@Injectable()
export class MulterProvider {
  private readonly logger = new Logger("Multer");

  createFolder(folder1: string, folder2: string) {
    try {
      this.logger.log("create uploads folder");
      fs.mkdirSync(path.join(__dirname, "../../../uploads"));
    } catch (err) {
      this.logger.log("uploads folder is already exist");
    }

    try {
      this.logger.log(`create ${folder1}folder into uploads foler`);
      fs.mkdirSync(path.join(__dirname, `../../../uploads/${folder1}`));
    } catch (err) {
      this.logger.log(`${folder1} is already exist`);
    }

    try {
      this.logger.log(`create ${folder2}folder into uploads folder`);
      fs.mkdirSync(path.join(__dirname, `../../../uploads/${folder2}`));
    } catch (err) {
      this.logger.log(`${folder2} is already exist`);
    }
  }

  storage(folder1: string, folder2: string): multer.StorageEngine {
    this.createFolder(folder1, folder2);

    return multer.diskStorage({
      destination(req, file, cb) {
        if (file.mimetype.includes("image")) {
          const folderName = path.join(
            __dirname,
            `../../../uploads/${folder1}`,
          );

          cb(null, folderName);
        } else {
          const folderName = path.join(
            __dirname,
            `../../../uploads/${folder2}`,
          );

          cb(null, folderName);
        }
      },
      filename(req, file, cb) {
        const ext: string = path.extname(file.originalname);

        const fileName = `${path.basename(
          file.originalname,
          ext,
        )}-${Date.now()}${ext}`;

        cb(null, fileName);
      },
    });
  }

  apply(folder1: string, folder2: string) {
    const result: MulterOptions = {
      storage: this.storage(folder1, folder2),
    };
    return result;
  }
}
// upload.module.ts
import { MulterProvider } from "src/model/upload/multer.provider";
import { TypeOrmModule } from "@nestjs/typeorm";
import { Module } from "@nestjs/common";
import { UploadService } from "../upload/services/upload.service";
import { UploadController } from "../upload/controllers/upload.controller";
import { ImagesEntity, VideosEntity } from "./entities/upload.entity";
import { UploadRepository } from "./upload.repository";

@Module({
  imports: [TypeOrmModule.forFeature([ImagesEntity, VideosEntity])],
  controllers: [UploadController],
  providers: [UploadService, UploadRepository, MulterProvider],
  exports: [UploadRepository],
})
export class UploadModule {}

 그리고 이미지를 업로드 할 컨트롤러에 MulterProvider를 적용시키기 위해 아래 처럼하였습니다.

@Controller("upload")
export class UploadController {
  constructor(
    private readonly uploadService: UploadService,
    private readonly multerProvider: MulterProvider,
  ) {}

  @UseInterceptors(
    FileInterceptor("image", this.multerProvider.apply("image", "video")),
  )

이 때 FileInterceptor() 함수의 this가 들어간 인자가 빨간색 에러가 뜨며 에러 내용은 개체가 'undefined'인거 같습니다 라고 뜹니다. 위 예시를 di하지 않고 this.multerProvider 대신 new를 사용해 클래스를 초기화 한다면 정상작동 하기는 합니다.

어찌보면 FileInterceptor에 this로 된 인자를 전달해서 데코레이터에 인자로 준거랑은 다른 맥락인거 같아서 아래처럼 테스트를 해봤는데 this에 '개체가 'undefined'인거 같습니다'라는 에러가 나는 것은 똑같습니다.

 private readonly te = "hello";

  @Get(this.te)
  test() {
   return "hello"
}

 

답변 1

답변을 작성해보세요.

0

데코레이터에서는 this 못 씁니다.

이승훈님의 프로필

이승훈

질문자

2022.06.23

아쉽네요 감사합니다!