I am building a logic to upload videos to cloudinary using node.js, next.js and multer package.
I have a mongodb document that I would like to store the video url and publicid of the video once cloudinary upload function completes.
This means that I would like to wait for the process to complete, sore it as part of my response before creating the document.
Unfortunately, I am unable to get this to work. The video upload takes time to complete. I would like to wait for the response to decide what to send back to the client.
Here is the cloudinary upload function:
export const largeFileUploader = async(props: {targetedFile: string})=>{
const {targetedFile} = props;
try {
cloudinary.uploader.upload_large(targetedFile,
{ resource_type: "video" ,
chunk_size: 6000000, folder: 'folderName', upload_preset: 'presetName' },
function(error, result) {
console.log(error, 'error')
if(error) throw 'Error encountered';
return result
});
} catch (error) {
console.log(error)
throw 'file upload error';
};
};
I wrote another function that can be invoked in a route:
const imageUploadFunct = async(req: Request, res: Response, eventType: events)=>{
const files = req?.files as Express.Multer.File[];
const imageUrl: string[] = [];
const publicId: string[] = [];
if(eventType === 'video_upload_event'){
const uploadResponse = await largeFileUploader({targetedFile: file?.path}) as any;
imageUrl.push(uploadResponse?.secure_url);
publicId.push(uploadResponse?.public_id);
if(file?.path){
removeFile({filePath: file?.path});
};
return { imageUrl, publicId };
}
};
Then in my controller, I have this:
export const httpUploadVideo = async (req: Request, res: Response)=>{
try {
const response = await imageUploaderFunc(req, res, 'video_upload_event');
return res.status(200).json(response)
} catch (error) {
return res.status(500).json('Something went wrong, refresh your page or contact support');
};
};
The cloudinary upload method takes time to complete the video upload before returning with response. Before then, my client already got response from me. Now, I need the cloudinary response to send to my client but before it can be ready, my code has already returned and sent response to client.
How do I make my code to wait until cloudinary returns a response before I send a response to the client?
I know there can be option for me to update the mongoose database background wise when cloudinary sends a a feedback by building something like an event hook. But I dont really wish to follow that path.
2
Answers
The
largeFileUploader
function isasync
, but it doesn’tawait
anything. The asynchronous operation therein is using a callback rather than a Promise:If the service provides an awaitable API, it is recommended to use that instead. If they don’t, one option is to wrap this callback structure in a Promise and return that so consuming code can
await
it. For example:I just checked your code carefully and almost correct, but you made some mistakes in
largeFileUploader
function.cloudinary.upload.upload_large
is async function so you should useawait
here to waits uploading results from cloudinary. But you didn’t usedawait
and handled the result incallback
ofupload_large
. In this case, the result will be returned once you already sent response to the client so it’s wrong. I provide updated code for it.