I’ve got this function which contains other nested async functions.
I’m unzipping a zipfile and then appending each HTMLImageElement
to an array.
However, the array is printing like this
16 is the correct number of images I’m expecting, but they’re undefined when I console.log()
them.
export async function fetchVisuals(TestID: number) { var zip = new JSZip(); const res = await fetch('*DJANGO URL*', { body: JSON.stringify(TestID), method: 'POST' }) let http_ok = res.ok const blob = await res.blob() var bufferPromise = await blob.arrayBuffer(); zip.loadAsync(bufferPromise).then(async ({files}) => { const mediaFiles = Object.entries(files).filter(([fileName]) => fileName.endsWith('.jpg'), ); if (!mediaFiles.length) { throw new Error('No media files found in archive'); } // I'm very confident the issue is to do with the below function let promiseArray = mediaFiles.map(function([,image]) { image.async('blob').then((blob: Blob | MediaSource) => { console.log("mediaFiles loop") const img = new Image(); img.src = URL.createObjectURL(blob) console.log(img) return img }) }) Promise.all(promiseArray).then(function(resultsArray) { console.log(resultsArray) }) }) }
I’m mapping the promise of each image to an array then doing Promise.all()
on this array, so I’m not sure why it’s still coming back as undefined
.
Inside of mediaFiles.map()
I do some prints and they print the img data successfully.
How can I fill this array with the HTMLImageElements
?
Advertisement
Answer
You don’t return your promise in the map function:
let promiseArray = mediaFiles.map(function([,image]) { image.async('blob').then((blob: Blob | MediaSource) => { console.log("mediaFiles loop") const img = new Image(); img.src = URL.createObjectURL(blob) console.log(img) return img }) })
Must become :
// I'm very confident the issue is to do with the below function let promiseArray = mediaFiles.map(function([,image]) { /*just there : */ return image.async('blob').then((blob: Blob | MediaSource) => { console.log("mediaFiles loop") const img = new Image(); img.src = URL.createObjectURL(blob) console.log(img) return img }) })
For your second question, you must await your promises and return their results :
export async function fetchVisuals(TestID: number) { var zip = new JSZip(); const res = await fetch('*DJANGO URL*', { body: JSON.stringify(TestID), method: 'POST' }) let http_ok = res.ok const blob = await res.blob() var bufferPromise = await blob.arrayBuffer(); const {files} = await zip.loadASync(bufferPromise); const mediaFiles = Object.entries(files).filter(([fileName]) => fileName.endsWith('.jpg'), ); if (!mediaFiles.length) { throw new Error('No media files found in archive'); } // I'm very confident the issue is to do with the below function let promiseArray = mediaFiles.map(function([,image]) { return image.async('blob').then((blob: Blob | MediaSource) => { console.log("mediaFiles loop") const img = new Image(); img.src = URL.createObjectURL(blob) console.log(img) return img }) }) return await Promise.all(promiseArray); }