I am attempting to retrieve the secure file URL provided by Cloudinary after successfully uploading the asset to their servers. Although I can upload the file to Cloudinary, when I try to view the response using console.log(res)
, I unfortunately receive '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