Having trouble accessing result object when attempting multiple uploads using upload_stream
I have an async function in my Node.js backend which I am using for adding a new product to my database and uploading related images. Here it is:
const cloudinary = require('cloudinary').v2;Running this as-is, I can upload an array of files. However, I can't manage to access the result object which contains the secure URL. The push I make within the createUploadStream() function doesn't seem to occur when I need it to, and the return value is an uploadStream which doesn't contain the URL I need to pass to my database.
const { Readable } = require('stream');
const addProduct = db => async (formData, files) => {
let img_urls = [];
function createUploadStream() {
return cloudinary.uploader.upload_stream({ folder: 'product-images' }, (err, result) => {
if (err) {
console.log(err)
throw (err)
}
img_urls.push({
url: result.secure_url,
public_id: result.public_id
})
return result;
})
}
const new_product = await db("products").returning(['id']).insert({
prod_name: formData.name,
description: formData.description,
price: Number(formData.price),
stock: Number(formData.stock),
category_id: Number(formData.category)
})
await Promise.all(files.map(async (file) => await Readable.from(file.buffer).pipe(createUploadStream())));
console.log(img_urls);
if (img_urls && img_urls.length > 0) {
console.log(img_urls)
for (let i = 0; i < img_urls.length; i++) {
await db('product_images').insert({ image_url: img_urls[i].url, product_id: new_product[0].id })
}
}
}
I saw this previous Cloudinary support thread related to upload_stream.
Correct way of uploading from buffer? – Cloudinary Support
I tried copying the solutions given in the above thread but they only seem suited for uploading a single file and, in addition, still did not work properly when I tried them. They still only returned an uploadStream object.
Correct way of uploading from buffer? – Cloudinary Support
I tried copying the solutions given in the above thread but they only seem suited for uploading a single file and, in addition, still did not work properly when I tried them. They still only returned an uploadStream object.
How can I refactor the above code to be able to access the result objects for multiple concurrent file uploads using upload_stream?
0
-
Found my own solution. Hopefully this might come in handy for someone.
const addProduct = db => async (formData, files) => {
function createUploadStream(readStream) {
return new Promise((resolve, reject) => {
readStream.pipe(
cloudinary.uploader.upload_stream({ folder: 'product-images' }, (err, result) => {
if (err) {
reject(err)
}
resolve(result.secure_url)
})
)
})
}
const new_product = await db("products").returning(['id']).insert({
prod_name: formData.name,
description: formData.description,
price: Number(formData.price),
stock: Number(formData.stock),
category_id: Number(formData.category)
})
const results = await Promise.all(files.map(async (file) => await createUploadStream(Readable.from(file.buffer))));
if (results && results.length > 0) {
for (let i = 0; i < results.length; i++) {
await db('product_images').insert({ image_url: results[i], product_id: new_product[0].id })
}
}
}0 -
Hi Samuel.
Thanks so much for providing that solution! I'm sure others will find it very useful.
If there's anything else you need assistance with, please don't hesitate to get in touch either here or by raising a support ticket with us.
Thanks,
-Danny0
Post is closed for comments.
Comments
2 comments