node.jsloopspromisessh2-sftp

looping inside SFTP promise not download file data to local file?


My overall issue is once i filtered the files which were added in the last 5 minutes i am looping over the returned array of objects. From there I'm appending the root remote file name with the name returned from files added in the last 5 minutes. the fastget writes nothing to my local file.

i've tested the appended route outside the loop and it works, am i losing my promise data inside the loop for some reason?

sftp
  .connect({
    host: "hostaddress",
    port: 22,
    username: "USERNAME",
    password: "PASSWORD"
  })
  .then(() => {
    return sftp.list(root);
  })
  .then(data => {
    //filters new files in last 5 min
    const filteredFile = data.filter(file => {
      let currentDate = moment();
      let CurrentTimeMinusFive = moment().subtract(5, "minutes");
      let allAccessTimes = file.accessTime;
      let parsedAccessTimes = moment(allAccessTimes);
      let filteredTime = moment(parsedAccessTimes).isBetween(
        CurrentTimeMinusFive,
        currentDate
      );
      //returns boolean if the file has been added in the last 5 minutes
      return filteredTime;
    });
    //returns full metadata in array of objects
    console.log(filteredFile);

    //not writing filedata from remote server to localfile
    let localPath = "/Users/me/Desktop/DOWNLOADEDSFTP/data.txt";
    filteredFile.forEach(file => {
      let name = file.name;
      return sftp.fastGet(
        `remote-path/${name}`,
        localPath
      );
    });
  })
  .then(() => {
    sftp.end();
  })
  .catch(err => {
    console.error(err.message);
  });

Solution

  • You are using forEach loop with promises which doesn't work the way you expect them to. You need to either use for..of or Promise.all if you can do things in parallel.

    for(const file of filteredFile) {
          let name = file.name;
          await sftp.fastGet(
            `remote-path/${name}`,
            localPath
          );
        });
    

    Make sure you put async like this

    .then(async data => {