Reputation: 179
I got this map function on a array:
foldersTreeImagesFiles.map( async (paragliderFolder) => {
const pathfolder = pathImagesParaglider + '/' + paragliderFolder.subfolderName;
const imagesUrl = await paragliderFolder.ImagesParagilder.reduce( async (UrlsImage, image, index) => {
const pathImage = pathfolder + '/' + image;
const folderCoulidinary = 'paraglider/' + paragliderFolder.subfolderName;
const resu = await uploadImage(pathImage, folderCoulidinary);
UrlsImage.name = paragliderFolder.subfolderName
UrlsImage[`photo_${index}`] = resu;
return UrlsImage
}, {})
console.log(imagesUrl);
})
The array exemple :
[
{
subfolderName: 'Arcus_Rs',
ImagesParagilder: [
'swing_arcus2rs_slider_arcus6.jpg',
'swing_arcus2rs_slider_arcus7.jpg',
'swing_arcus2rs_slider_arcuslim4.jpg',
'swing_arcus2rs_slider_arcuslime9.jpg'
],
color: [
'swing_arcus2rs_flame.png',
'swing_arcus2rs_lime.png',
'swing_arcus2rs_nightshade.png',
'swing_arcus2rs_ocean.png'
]
},
{
subfolderName: 'Coden_Pro',
ImagesParagilder: [ 'DSC5495.jpg' ],
color: [ 'Air.png', 'Earth.png', 'Fire.png', 'Water.png' ]
},
{
subfolderName: 'Tonic_2',
ImagesParagilder: [
'DSC5349r.jpg',
'DSC6647r.jpg',
'P1044262r.jpg',
'P1044438r.jpg',
'P1044656r.jpg'
],
color: [ 'Lind.png', 'Mustard.png' ]
}
]
So i got this result :
{
name: 'Arcus_Rs',
photo_0: 'url********'
}
{
name: 'Coden_Pro',
photo_0: 'url********'
}
{
name: 'Tonic_2',
photo_0: 'url********'
}
i got only one photo, i should have more photo, so for me it the await of the reduce who doesn't work.
If i try const imagesUrl = await Promies.all(paragliderFolder.ImagesParagilder.reduce( ect...)
i have a error: TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
i don't understand why the console log doesn't wait the end of the reduce.
Upvotes: 1
Views: 89
Reputation: 179
Hello after many research and trials here what i find.
the array.reduce() send only one promise so we can't use the Promise.all().
Here the trick to use a reduce with array of promise:
const array = [4, 7, 78];
const postsPromise = array.reduce((acc, element, index) => {
return acc.then(async result => {
const post = await fetch(`https://jsonplaceholder.typicode.com/posts/${element}`).then(res => res.json());
return { ...result, [`Id_${index}`]: post.title };
});
}, Promise.resolve({}));
const posts = await postsPromise;
console.log(posts);
The Promise.resolve send a Promise already resolved and we loop over it
Upvotes: 0
Reputation: 15796
When you do await
in your reducer, the function immediately returns a Promise and quits. At the second iteration, UrlsImage
is actually the Promise from the first iteration, not the object you put into the reducer. I think this is not what you want.
Try something like this:
const promises = paragliderFolder.ImagesParagilder.map( async (image, index) => {
const pathImage = pathfolder + '/' + image;
const folderCoulidinary = 'paraglider/' + paragliderFolder.subfolderName;
const resu = await uploadImage(pathImage, folderCoulidinary);
return [`photo_${index}`, resu]
})
const entries = await Promise.all(promises)
const imagesUrl = Object.fromEntries(entries)
This will load each image and give you a tuple from which you can build what I assume you want imagesUrl
to look like. Not sure about the name
property, it seems like you wanted to override it in every iteration.
Here is a dummy-application using it:
function uploadImage(pathImage, folderCoulidinary){
return new Promise((resolve) => {
resolve('uploaded to:' + pathImage)
})
}
const paragliderFolder = {
ImagesParagilder: [
'img1', 'img2'
]
}
const pathfolder = 'pathfolder'
async function runit(){
const promises = paragliderFolder.ImagesParagilder.map( async (image, index) => {
const pathImage = pathfolder + '/' + image;
const folderCoulidinary = 'paraglider/' + paragliderFolder.subfolderName;
const resu = await uploadImage(pathImage, folderCoulidinary);
return [`photo_${index}`, resu]
})
const entries = await Promise.all(promises)
return Object.fromEntries(entries)
}
runit().then(o => console.log(o))
Upvotes: 2