How can I get progress of file uploading from uploader.upload_stream and pass it to api
I'm developing nextjs app with api routes, I have a route to upload file to cloudinary localhost/api/files/upload. There I send files with axios and receive axios uploadProgressEvent to display it on web page. I see that progress works fine when I upload file to api route, at 100% upload I need to wait more because file is streamed with uploader.upload_stream to cloudinary. How can I pass progress from uploader.upload_stream to axios uploadProgress event with through my api? So the uploadProgressEvent shows uploading to api route and from api route to cloudinary?
Api route
export async function POST(req: NextRequest) { try { const formData = await req.formData(); const formDataEntryValues = Array.from(formData.values()); for (const formDataEntryValue of formDataEntryValues) { if (typeof formDataEntryValue === "object" && "arrayBuffer" in formDataEntryValue) { const file = formDataEntryValue as unknown as Blob; if (file.size > config.maxFileSize) { return BadRequest(`Max file size is ${config.maxFileSizeAsString}`); } const buffer = Buffer.from(await file.arrayBuffer()); const response = await uploadWrapper(buffer); return NextResponse.json(response, { status: 200 }); } } } catch (error: any) { return NextResponse.json(error, { status: 500 }); } } const uploadWrapper = async (buffer: Buffer) => { return new Promise(async (resolve, reject) => { const cloud_upload_stream = await cloudinary.v2.uploader.upload_stream({ folder: config.storePath }, (error, result) => { if (error) { reject(error); } else { resolve(result); } }); streamifier.createReadStream(buffer).pipe(cloud_upload_stream); }) }
OnUploadingProgressChange
const onUploadProgressChange = (id: string) => (event: AxiosProgressEvent) => { if (event && event.loaded && event.total) { const uploadingFile = uploadedFilesRef.current.find((f: UploadedFileType) => f.id === id); if (uploadingFile) { const newProgress = Math.round((100 * event.loaded) / event.total); const updatedFile: UploadedFileType = { ...uploadingFile, progress: newProgress }; setUploadedFiles(uploadedFilesRef.current.map((f) => f.id === id ? updatedFile : f)); } } }
Function to upload file to api
export async function upload(file: File, onUploadProgress: (e: AxiosProgressEvent) => void) { try { const formData = new FormData(); formData.append("file", file); const response = await axios.post("/api/files/upload", formData, { headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: onUploadProgress }) return response.data; } catch (error: any) { throw new Error(`Failed to upload a file: ${error.response.data.message}`); } }
Comments
-
Hi there,
Thanks for reaching out! Unfortunately, since the
cloudinary.v2.uploader.upload_stream
method doesn't provide a direct progress event like axios does, it's not possible to directly sync the progress from your API route to Cloudinary. There might be a custom solution you can implement yourself.Kind regards,
Tamara
0