简体   繁体   中英

Not returning the file instance after uploading the files to cloudinary nestjs

I am trying to get the secure file url as returned by cloudinary after successful uploading of the asset to their servers sucessfuly. I am able upload the file to cloudinary but when i try to see the response through console.log(res) but unfortunately I am getting undefined.

Codes :-

// cloudinary.service.ts
import { Injectable } from '@nestjs/common';
import { UploadApiErrorResponse, UploadApiResponse, v2 } from 'cloudinary';
import toStream = require('buffer-to-stream');
import { ConfigService } from '@nestjs/config';

@Injectable()
export class CloudinaryService {
    constructor(private configService: ConfigService) {}
    async uploadMedia(
        file: Express.Multer.File,
    ): Promise<UploadApiResponse | UploadApiErrorResponse> {
        return new Promise((resolve, reject) => {
            const upload = v2.uploader.upload_stream(
                {
                    upload_preset: this.configService.get('CLOUDINARY_UPLOAD_PRESET'),
                },
                (error, result) => {
                    if (error) return reject(error);
                    resolve(result);
                },
            );
            toStream(file.buffer).pipe(upload);
        });
    }
}
// cloudinary.module.ts
import { Module } from '@nestjs/common';
import { CloudinaryProvider } from './cloudinary.provider';
import { CloudinaryService } from './cloudinary.service';
import { ConfigModule } from '@nestjs/config';

@Module({
    imports: [ConfigModule],
    providers: [CloudinaryProvider, CloudinaryService],
    exports: [CloudinaryProvider, CloudinaryService],
})
export class CloudinaryModule {}
// cloudinary.provider.ts
import { v2 } from 'cloudinary';
export const CloudinaryProvider = {
    provide: `${process.env.CLOUDINARY_PROVIDER_TOKEN}`,
    useFactory: () => {
        return v2.config({
            cloud_name: `${process.env.CLOUDINARY_CLOUD_NAME}`,
            api_key: `${process.env.CLOUDINARY_API_KEY}`,
            api_secret: `${process.env.CLOUDINARY_API_SECRET}`,
        });
    },
};
// media.controller.ts
import {
    Controller,
    Post,
    UploadedFile,
    UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { MediaService } from './media.service';

@Controller('media')
export class MediaController {
    constructor(private mediaService: MediaService) {}

    @Post('upload')
    @UseInterceptors(FileInterceptor('file'))
    upload(@UploadedFile() file: Express.Multer.File) {
        return this.mediaService.uploadMediaToCloudinary(file);
    }
}
// media.service.ts
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CloudinaryService } from '../cloudinary/cloudinary.service';

@Injectable()
export class MediaService {
    constructor(private cloudinaryService: CloudinaryService) {}

    async uploadMediaToCloudinary(file: Express.Multer.File) {
        return await this.cloudinaryService.uploadMedia(file).catch(error => {
            throw new HttpException(
                {
                    message: error.message,
                },
                HttpStatus.INTERNAL_SERVER_ERROR,
            );
        });
    }
}
// media.module.ts
import { Module } from '@nestjs/common';
import { CloudinaryModule } from 'src/cloudinary/cloudinary.module';
import { MediaController } from './media.controller';
import { MediaService } from './media.service';

@Module({
    imports: [CloudinaryModule],
    controllers: [MediaController],
    providers: [MediaService],
})
export class MediaModule {}
// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { MongooseModule } from '@nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CloudinaryModule } from './cloudinary/cloudinary.module';
import { MediaModule } from './media/media.module';

@Module({
    imports: [
        ConfigModule.forRoot({
            envFilePath: '.env',
        }),
        MongooseModule.forRootAsync({
            imports: [ConfigModule],
            useFactory: async (configService: ConfigService) => ({
                uri: configService.get<string>('MONGO_URI'),
            }),
            inject: [ConfigService],
        }),
        CloudinaryModule,
        MediaModule,
    ],
    controllers: [AppController],
    providers: [AppService],
})
export class AppModule {}

Nestjs File Upload Docs :- https://docs.nestjs.com/techniques/file-upload[enter link description here] 1

Testing Client :- https://codesandbox.io/s/file-link-generator-example-app-react-byez4?file=/src/App/UploadFile.js

I had to do this one in a project. I used the Cloudinary upload API instead of the upload_stream api. I also had to base64 encode the file that was sent frm the frontend. Here is how i did it an it worked.

@Post()
    @UseInterceptors(FileInterceptor('file'))
    async uploadFile(@UploadedFile() file, @Body() body) {

        const dto = JSON.parse(body.reportData);

        if (file) {
            const imageBuffer = await this.encodeImageForCloudinary(file.buffer, file.mimetype);
            const cloudinaryStoredImage = await this.cloudinaryService.uploadImg(imageBuffer);
            dto.imageUrl = cloudinaryStoredImage.url;
        }
        return await this.save(dto);
    }
    async save(@Body() dto) {
        let report = this.mapToEntity(dto);
        report = await this.reportService.add(report);
        return this.mapToDTO(report);
    }

    encodeImageForCloudinary(data, mediaType) {
        if (!data || !mediaType) {
            this.logger.log('ImageDataURI :: Error :: Missing some of the required params: data, mediaType ');
                     return null;
        }

        mediaType = (/\//.test(mediaType)) ? mediaType : 'image/' + mediaType;
        const dataBase64 = (Buffer.isBuffer(data)) ? data.toString('base64') : Buffer.from(data).toString('base64');
        const dataImgBase64 = 'data:' + mediaType + ';base64,' + dataBase64;

        return dataImgBase64;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM