1

Update: I added a brief pause after writing to the file, it was only then did the shell commands work.

async function testRun() {
    await createInsertCurlReq.createInsertCurlReq(process.argv[2]);
    await timeout(3000);
    shell.chmod("+x", "./curl.sh");
    shell.exec("./curl.sh");
  }
}

Original Question

My .then() block after createInsertCurlReq.createInsertCurlReq(process.argv[2]) does not run. How should I rewrite this so that it does? I noticed if I don't remove the file and just append to, the script runs.

    async function testRun() {

        if (fs.existsSync('./curl.sh')) {
          shell.rm('-rf', './curl.sh');
        }

        createInsertCurlReq.createInsertCurlReq(process.argv[2]).then(() => {
           shell.chmod('+x', './curl.sh');
           shell.exec('./curl.sh')
           return
        })

      }
    }

curlCreation.js



     function createInsertCurlReq(filePath) {
          return utils
            .readJSONFileOnDisk(filePath)
            .then(data => {
              obj = JSON.parse(data);
              let resultArr = [];
              for (let key in obj) {
                for (let innerKey in obj[key]) {
                  let arrayNew = {};
                  arrayNew[key] = obj[key][innerKey].resolved;
                  resultArr.push(arrayNew);
                }
              }
              return resultArr;
            })
            .then(data => {
              if (!fs.existsSync("./curl.sh")) {
                shell.touch("./curl.sh");
              }
              return data;
            })
            .then(data => {
              for (let i = 0; i < data.length; i++) {
                for (let key in data[i]) {
                  fs.appendFile(
                    "curl.sh",
                    `curl -X POST -H "xxx",
                    function(err) {
                      if (err) throw err;
                    }
                  );
                }
              }
            });
        }
        module.exports = { createInsertCurlReq: createInsertCurlReq };
David Trinh
  • 319
  • 1
  • 12

2 Answers2

0

I believe the problem is you have a synchronous loop in the last then call of createInsertCurlReq. Different, but related problem: Using async/await with a forEach loop

Try replacing it with something like:

const {promisify} = require('util');

const appendFileAsync = promisify(fs.appendFile);
// ...
.then(data => Promise.all(data.map(() => appendFileAsync(
  "curl.sh",
  `curl -X POST -H "xxx"`
).catch(err => { throw err; }))));

That way all fs.appendFile calls will settle before going to the next then.

If you don't mind pulling in a module, you could also use async-af to refactor to an async forEach method:

const {promisify} = require('util');
const AsyncAF = require('async-af');

const appendFileAsync = promisify(fs.appendFile);
// ...
.then(data => AsyncAF(data).forEach(() => appendFileAsync(
  "curl.sh",
  `curl -X POST -H "xxx"`
).catch(err => { throw err; })));
Scott Rudiger
  • 1,224
  • 12
  • 16
0

In createInsertCurlReq you use then chaining jsut to pass an array when there is no asynchronous operations. try this format:

async function testRun() {
  if (fs.existsSync('./curl.sh')) {
    shell.rm('-rf', './curl.sh');
  }
  await createInsertCurlReq.createInsertCurlReq(process.argv[2])
  shell.chmod('+x', './curl.sh');
  shell.exec('./curl.sh');
}

async function createInsertCurlReq(filePath) {
  const data = await utils.readJSONFileOnDisk(filePath);
  const obj = JSON.parse(data);
  let resultArr = [];
  for (let key in obj) {
    for (let innerKey in obj[key]) {
      let arrayNew = {};
      arrayNew[key] = obj[key][innerKey].resolved;
      resultArr.push(arrayNew);
    }
  }
  if (!fs.existsSync("./curl.sh")) {
    shell.touch("./curl.sh");
  }
  for (let i = 0; i < resultArr.length; i++) {
    for (let key in resultArr[i]) {
      fs.appendFileSync(
        "curl.sh",
        `curl -X POST -H "xxx"`
      );
    }
  }
}
Tarek Essam
  • 3,602
  • 2
  • 12
  • 21
  • I've added an update, it looks like I need to have a brief pause after the await, which doesn't makes sense to me. You are right that I'm trying to do a synchronous action, I want to run the curl.sh after the file finishes writing. I was only able to get to work after I added a 3 sec timeout, why is that? – David Trinh Oct 22 '18 at 23:08
  • @DavidTrinh I'm pretty sure adding the 3 sec timeout gives the `fs.appendFile` calls a chance to finish. You can take it out if you make sure your last `then` call in `createInsertCurlReq` is asynchronous. Currently your for loop fires off a bunch of async `fs.appendFile` calls, but runs synchronously and returns an implicit `undefined`. Basically, it's not done appending to the file before you execute `./curl.sh`. – Scott Rudiger Oct 22 '18 at 23:16
  • You are right @DavidTrinh fs.appendFile run asynchronously so use fs.appendFileSync and remove the timeout and try again, I updated the answer:). – Tarek Essam Oct 22 '18 at 23:19
  • That would also work; either append to the file sync or append async but make sure the appending is done before moving on. :) – Scott Rudiger Oct 22 '18 at 23:24