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.
JavaScript
x
32
32
1
export async function fetchVisuals(TestID: number) {
2
var zip = new JSZip();
3
const res = await fetch('*DJANGO URL*', {
4
body: JSON.stringify(TestID),
5
method: 'POST'
6
})
7
let http_ok = res.ok
8
const blob = await res.blob()
9
var bufferPromise = await blob.arrayBuffer();
10
zip.loadAsync(bufferPromise).then(async ({files}) => {
11
const mediaFiles = Object.entries(files).filter(([fileName]) =>
12
fileName.endsWith('.jpg'),
13
);
14
if (!mediaFiles.length) {
15
throw new Error('No media files found in archive');
16
}
17
// I'm very confident the issue is to do with the below function
18
let promiseArray = mediaFiles.map(function([,image]) {
19
image.async('blob').then((blob: Blob | MediaSource) => {
20
console.log("mediaFiles loop")
21
const img = new Image();
22
img.src = URL.createObjectURL(blob)
23
console.log(img)
24
return img
25
})
26
})
27
Promise.all(promiseArray).then(function(resultsArray) {
28
console.log(resultsArray)
29
})
30
})
31
}
32
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:
JavaScript
1
11
11
1
let promiseArray = mediaFiles.map(function([,image]) {
2
image.async('blob').then((blob: Blob | MediaSource) => {
3
console.log("mediaFiles loop")
4
const img = new Image();
5
img.src = URL.createObjectURL(blob)
6
console.log(img)
7
return img
8
})
9
})
10
11
Must become :
JavaScript
1
12
12
1
// I'm very confident the issue is to do with the below function
2
let promiseArray = mediaFiles.map(function([,image]) {
3
/*just there : */ return image.async('blob').then((blob: Blob | MediaSource) => {
4
console.log("mediaFiles loop")
5
const img = new Image();
6
img.src = URL.createObjectURL(blob)
7
console.log(img)
8
return img
9
})
10
})
11
12
For your second question, you must await your promises and return their results :
JavaScript
1
31
31
1
export async function fetchVisuals(TestID: number) {
2
var zip = new JSZip();
3
const res = await fetch('*DJANGO URL*', {
4
body: JSON.stringify(TestID),
5
method: 'POST'
6
})
7
let http_ok = res.ok
8
const blob = await res.blob()
9
var bufferPromise = await blob.arrayBuffer();
10
const {files} = await zip.loadASync(bufferPromise);
11
const mediaFiles = Object.entries(files).filter(([fileName]) =>
12
fileName.endsWith('.jpg'),
13
);
14
if (!mediaFiles.length) {
15
throw new Error('No media files found in archive');
16
}
17
// I'm very confident the issue is to do with the below function
18
let promiseArray = mediaFiles.map(function([,image]) {
19
return image.async('blob').then((blob: Blob | MediaSource) => {
20
console.log("mediaFiles loop")
21
const img = new Image();
22
img.src = URL.createObjectURL(blob)
23
console.log(img)
24
return img
25
})
26
})
27
return await Promise.all(promiseArray);
28
}
29
30
31