0
const downloadurl = ['url1', 'url2']
const filename = 'run.jar'

downloadurl.forEach((urls) => {
    https.get(urls, (httpsres) => {
        const path = `${installationdirectory}/${filename}`
        const filePath = fs.createWriteStream(path);
        httpsres.pipe(filePath);
        filePath.on('finish',() => {

            filePath.close();
            const filesize = fs.statSync(path).size
            // Verify if the size of the file is smaller than 1Kb
            if((filesize / 1024) < 1) return;

            // Want to skip this console.log if the file size is smaller than 1Kb and try with the other downloadurl (Hence why the downloadurl.forEach)
            console.log('File downloaded!'); 


        })
    })
})

I'm using the https module from NodeJS which doesn't give an error if the download url doesn't exist, as it just creates a 1-byte file with the run.jar name instead. So, I want to make it stop executing code and try to download with the other URL if the size of the file is smaller than 1Kb, any ideas?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • don't use `forEach` if you want to break out of the loop, use a regular for loop or for...in or for...of - or maybe `.some` or `.every` ... – Jaromanda X Sep 20 '22 at 01:25
  • > which doesn't give an error if the download url doesn't exist.. You can test for the `statusCode` before writing the file. – Matt Sep 20 '22 at 01:45

3 Answers3

0
  1. you can use every() loop. and when you want to break the loop just don't return anything.

// Prints "1, 2, 3"
[1, 2, 3, 4, 5].every(v => {
  if (v > 3) {
    return false;
  }

  console.log(v);
  // Make sure you return true. If you don't return a value, `every()` will stop.
  return true;
});
  1. or you can change length of array using third
const myNums = [1, 2, 3, 4, 5];
myNums.forEach((v, index, arr) => {
  console.log(v);
  if (val > 3) {
    arr.length = index + 1; // Behaves like `break`
  }
}
Saad Ramay
  • 152
  • 1
  • 11
0

If using a callback structure, as you are at the moment, you could try a recursive function to try further downloads.

function tryDownload(downloadUrls):
    // try download the first
    https.get(downloadUrls[0], (res) => {
        // read it, etc
        // ...

        // if too small, try the next urls
        if ((filesize / 1024) < 1)
            tryDownload(downloadUrls.slice(1));
        else
            // success!
            // ...
    })

You may find it clear to restructure this as an asynchronous function, though. In pseudocode:

    for each url in download urls
        res = await download url
        if res indicates success
            handle the res
            return
Luke
  • 1,724
  • 1
  • 12
  • 17
0

Used @Matt's comment as it was the simplest one to implement (And I didn't know that the HTTPS module does have a response to check the status code).

const downloadurl = ['url1', 'url2']
const filename = 'run.jar'

downloadurl.forEach((urls) => {
    https.get(urls, (httpsres) => {
        if(httpsres.statusCode !== 200) {
            return console.log(`Attempt of downloading failed with ${httpsres.statusCode} error! Retrying with another download URL`);
        } else {

        const path = `${installationdirectory}/${filename}`
        const filePath = fs.createWriteStream(path);
        httpsres.pipe(filePath);
        filePath.on('finish',() => {

            filePath.close();
            const filesize = fs.statSync(path).size
            // Verify if the size of the file is smaller than 1Kb
            if((filesize / 1024) < 1) return;

            // Want to skip this console.log if the file size is smaller than 1Kb and try with the other downloadurl (Hence why the downloadurl.forEach)
            console.log('File downloaded!'); 

        })
        }
    })
})
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197