I am trying to call fetch method in the promise.allSettled. But the method return the value as empty. fetch is taking time and the response is returned before.
Desired result: I want all the images base64 in the array. But it is returning as empty.
There is the code.
(async function getData() {
results = results.recordset;
let i = 0;
const result = await Promise.allSettled(results.map(async (record) => {
(async function getData() {
var file = record.Path.split('Images');
//file = file[1].replaceAll('\\','/');
var file_path = file[1].replaceAll('\\', '/') + "/" + record.FileName;
var img_url = "localhost"+file_path;
let file_data_response = await reportModel.fetchTiff(img_url);
let base64Image = Buffer.from(file_data_response, 'binary').toString('base64');
let imgSrc = "data:png;base64,"+base64Image;
//let imgSrc = '';
let imgImg = '<img src='+img_url+' alt="Remote Image" />';
console.log(imgImg);
response.img.push(imgImg);
})();
})).then((results) => {
});
return resolve(response);
})();
exports.fetchTiff = function(image_url) {
return new Promise((resolve, reject) => {
var response = 0;
(async function getData() {
// let responsezz = await axios.get(image_url, {responseType: 'arraybuffer'});//.then(res => {return resolve(res);})
// response = await responsezz.data;
let responsezz = await fetch(image_url);
response = await responsezz.blob();
console.log(response);
return resolve(response);
})();
});
}
Took an initiative to rewrite your code for better readability.
Main Function to Fetch and Process Images: The fetchAndProcessImages function processes each image record, fetches the image, converts it to base64, and then creates an HTML image tag. It also returns the object with an array of images you intend to retrieve.
async function fetchAndProcessImages(results) {
const response = { img: [] };
results = results.recordset;
// Using Promise.allSettled to handle each record asynchronously
const fetchPromises = results.map(async (record) => {
try {
// Construct the image URL
const imgUrl = constructImageUrl(record);
// Fetch and convert the image to base64
const base64Image = await fetchImageAsBase64(imgUrl);
// Construct the image HTML and push it to the response
const imgTag = createImageTag(base64Image);
response.img.push(imgTag);
return { status: "fulfilled", value: imgTag };
} catch (error) {
console.error(
`Error processing image for record ${record.FileName}:`,
error
);
return { status: "rejected", reason: error.message };
}
});
await Promise.allSettled(fetchPromises);
console.log("All images processed:", response.img);
return response;
}
Helper Functions:
Constructing an image URL:
function constructImageUrl(record) {
const filePath = record.Path.split("Images")[1].replace(/\\/g, "/");
return `http://localhost${filePath}/${record.FileName}`;
}
Converting to base64: Converting an image to a base64 string using a buffer involves first fetching the image as an array buffer for binary representation. Then function converts this binary data into a base64-encoded string, allowing it to be embedded directly in HTML
async function fetchImageAsBase64(url) {
const response = await fetchTiff(url);
const arrayBuffer = await response.arrayBuffer();
return Buffer.from(arrayBuffer).toString("base64");
}
Separate function to extract image tag creation:
function createImageTag(base64Image) {
return `<img src="data:image/png;base64,${base64Image}" alt="Remote Image" />`;
}
And fetching image: This function ensures that any HTTP errors during the fetch are caught and logged properly. It’s crucial for diagnosing issues with remote image URLs.
async function fetchTiff(imageUrl) {
try {
const response = await fetch(imageUrl);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response;
} catch (error) {
console.error(`Error fetching image from ${imageUrl}:`, error);
throw error;
}
}
The full code example:
// Main function to fetch and process image data
async function fetchAndProcessImages(results) {
const response = { img: [] };
results = results.recordset;
// Using Promise.allSettled to handle each record asynchronously
const fetchPromises = results.map(async (record) => {
try {
const imgUrl = constructImageUrl(record);
const base64Image = await fetchImageAsBase64(imgUrl);
const imgTag = createImageTag(base64Image);
response.img.push(imgTag);
return { status: "fulfilled", value: imgTag };
} catch (error) {
console.error(
`Error processing image for record ${record.FileName}:`,
error
);
return { status: "rejected", reason: error.message };
}
});
await Promise.allSettled(fetchPromises);
console.log("All images processed:", response.img);
return response;
}
// Helper functions
function constructImageUrl(record) {
const filePath = record.Path.split("Images")[1].replace(/\\/g, "/");
return `http://localhost${filePath}/${record.FileName}`;
}
async function fetchImageAsBase64(url) {
const response = await fetchTiff(url);
const arrayBuffer = await response.arrayBuffer();
return Buffer.from(arrayBuffer).toString("base64");
}
function createImageTag(base64Image) {
return `<img src="data:image/png;base64,${base64Image}" alt="Remote Image" />`;
}
async function fetchTiff(imageUrl) {
try {
const response = await fetch(imageUrl);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response;
} catch (error) {
console.error(`Error fetching image from ${imageUrl}:`, error);
throw error;
}
}