Reputation: 757
I have a script that reads an excel file and gets data from a specific column to perform a search on the Google Maps API where I use axios. For each request made, I need to save it in the newFileList
variable. After completing all the requests, I must save the contents of this variable in a file. However, whenever I run my code, the file is being saved without the content of the newFileList
variable. How do I wait for all requests to finish before being able to save the content in the file?
Note: the reading, writing and requesting data are working. I just need the rescue to happen only after all the loop requests are finished. I tried to solve by placing the loop inside a promisse and at the end of the execution of this loop I used resolve
.
const xlsx = require("node-xlsx");
const fs = require("fs");
const coordinate = require("./coordinate");
const resourcePath = `${__dirname}/resources`;
const contentFile = xlsx.parse(`${resourcePath}/file-2.xlsx`)[0].data;
const newFile = [[...contentFile, ...["Latitude", "Longitude"]]];
for (let i = 1; i < contentFile.length; i++) {
const data = contentFile[i];
const address = data[2];
coordinate
.loadCoordinates(address)
.then((response) => {
const { lat, lng } = response.data.results[0].geometry.location;
newFile.push([...data, ...[lat.toString(), lng.toString()]]);
})
.catch((err) => {
console.log(err);
});
}
console.log(newFile);
//The code below should only be executed when the previous loop ends completely
var buffer = xlsx.build([{ name: "mySheetName", data: newFile }]); // Returns a buffer
fs.writeFile(`${resourcePath}/file-3.xlsx`, buffer, function (err) {
if (err) {
return console.log(err);
}
console.log("The file was saved!");
});
The coordinate file:
const axios = require("axios");
module.exports = {
loadCoordinates(address) {
const key = "abc";
return axios
.get(`https://maps.googleapis.com/maps/api/geocode/json`, {
params: {
address,
key,
},
})
},
};
Upvotes: 0
Views: 691
Reputation: 888
You need to use Promise.all()
to wait until all the promises are resolved. After that execute the writeToFile part. For more info on Promise.all()
, you can refer https://www.javascripttutorial.net/es6/javascript-promise-all/
const requestPromiseArray = [];
for (let i = 1; i < contentFile.length; i++) {
const data = contentFile[i];
const address = data[2];
requestPromiseArray.push(coordinate
.loadCoordinates(address))
}
Promise.all(requestPromiseaArray).then(results=>{
// Handle "results" which contains the resolved values.
// Implement logic to write them onto a file
var buffer = xlsx.build([{ name: "mySheetName", data: results }]);
fs.writeFile(`${resourcePath}/file-3.xlsx`, buffer, function (err) {
if (err) {
return console.log(err);
}
console.log("The file was saved!");
});
})
Upvotes: 1
Reputation: 410
Will using an async IIFE help?
const xlsx = require("node-xlsx");
const fs = require("fs");
const coordinate = require("./coordinate");
const resourcePath = `${__dirname}/resources`;
const contentFile = xlsx.parse(`${resourcePath}/file-2.xlsx`)[0].data;
const newFile = [[...contentFile, ...["Latitude", "Longitude"]]];
(async() => {
try{
for (let i = 1; i < contentFile.length; i++) {
const data = contentFile[i];
const address = data[2];
await coordinate
.loadCoordinates(address)
.then((response) => {
const { lat, lng } = response.data.results[0].geometry.location;
newFile.push([...data, ...[lat.toString(), lng.toString()]]);
})
.catch((err) => {
console.log(err);
});
}
console.log(newFile);
//The code below should only be executed when the previous loop ends completely
var buffer = xlsx.build([{ name: "mySheetName", data: newFile }]); // Returns a buffer
fs.writeFile(`${resourcePath}/file-3.xlsx`, buffer, function (err) {
if (err) {
return console.log(err);
}
console.log("The file was saved!");
});
} catch(e) {
console.log(e)
}
})();
Do note that I added await before coordinate.loadCoordinates
, in order to make sure the first axios request is finished before we proceed to the next one.
Upvotes: 1