function getting executed at the start of for loop instead of after it

Issue

So I’m trying to execute some code after a for loop in nodejs file

let DirectoriesDHRD = getDirectories('.\\captures\\ref');
for (let i = 0; i < DirectoriesDHRD.length; i++) {
//some things I coded
 if (i==DirectoriesDHRD.length-1)
{
//execute this
}

I’ve already seen a similar issue and one of the solution was to do that conditional statement, but it didn’t work for me. I’ve tried to debug the issue and I noticed that the loop iterator I get to its limit value (DirectoriesDHRD.length-1), then it executes the code inside the conditional statement before executing the other code outside of it.

It s like this is what happening:

for (let i = 0; i < DirectoriesDHRD.length; i++) 
{
    // conditional statement code
}

for (let i = 0; i < DirectoriesDHRD.length; i++) 
{
    // other code
}

How can I fix this ?

EDIT: here’s the code I’ve been working on

for (let i = 0; i < DirectoriesDHRD.length; i++) {
    let DirectoriesSCENARIO= getDirectories('.\\captures\\ref\\'+DirectoriesDHRD[i]);
    for (let j=0;j<DirectoriesSCENARIO.length;j++){
        let dirtestresult = path.join('VisualTests',DirectoriesDHRD[i],DirectoriesSCENARIO[j]);
        let dirref = path.join('captures','ref',DirectoriesDHRD[i],DirectoriesSCENARIO[j]);
        let dirtest= path.join('captures','test',DirectoriesDHRD[i],DirectoriesSCENARIO[j]);
        if (!fs.existsSync(dirtestresult)) {
            fs.mkdirSync(dirtestresult,{ recursive: true });
        }
        fs.readdir(dirref, function (err, files) {
            let TestResult="";
            if (err) {
                console.error("Could not list the directory.", err);
                process.exit(1);
            }
            else if (files.length == 0) {
                console.log("test skipped or pending");
                TestResult="skipped/pending";
            }
            else {
                TestResult="passed";
                files.forEach(function (file,Status) {

                    var filepathref=path.join(dirref, file);
                    var filepathtest=path.join(dirtest,file);
                    if (fs.existsSync(filepathtest))
                    {
                        Status=compare(file,filepathref,filepathtest,dirtestresult);
                        if (Status=="failed"){
                            TestResult="failed";
                        }
                    }
                    else {
                        console.log("test missing screenshots");
                        TestResult="failed";
                    }
                });
    
            }
            switch (TestResult) {
                case 'passed':
                  pass++;
                  break;
                case 'skipped/pending':
                  skip++;
                  break;  
                case 'failed':
                  fail++;
                  break;
                default:
                  console.log(`error`);
            }
            let Test={
                name : DirectoriesSCENARIO[j],
                tag : DirectoriesDHRD[i],
                status : TestResult
            }; 
            
            let TestJson=JSON.stringify(Test, null, "\t");
            alltests.push(Test);
            console.log(alltests[i]);
            fs.writeFile(dirtestresult+"\\test.json", TestJson, (err) => {
                if (err)
                  console.log(err);
                else {
                  console.log("File written successfully\n");
                }
              });
    
       
        });
    }
   if (i==DirectoriesDHRD.length-1)
   {
    let result=JSON.stringify({pass: pass,fail: fail, skip :skip},null,"\t");
    fs.writeFile(".\\VisualTests\\result.json", result, (err) => {
        if (err)
          console.log(err);
        else {
          console.log("Result File written successfully\n");
        }
      });
    let jsonresult=JSON.stringify(alltests,null,"\t");
    console.log("///////////////////////");
    console.log(jsonresult);
    fs.writeFile(".\\VisualTests\\Tests_results.json",jsonresult,(err)=>{
        if (err)
        console.log(err);
      else {
        console.log("Result File written successfully\n");
      }
    }); 

   } 
    
}

getdirectories:

function getDirectories(path) {
    return fs.readdirSync(path).filter(function (file) {
        return fs.statSync(path + '/' + file).isDirectory();
    });
}

compare:

function compare(file,filepathref,filepathtest,dirtestresult){
    var Status="passed";
    var imageref = PNG.sync.read(fs.readFileSync(filepathref));
    var imagetest=PNG.sync.read(fs.readFileSync(filepathtest));
    var i=file.replace(/\.[^/.]+$/, "");
    var {width, height} = imageref;
    var diff = new PNG({ width, height });
    var result=pixelmatch(imageref.data, imagetest.data, diff.data, width, height, { threshold: 0.4 ,alpha:1});
    fs.writeFileSync(dirtestresult+"\\"+i+".png", PNG.sync.write(diff));
    var percent=(result*100)/(width*height);
        console.log(percent);
        if (percent>15)
        {
            Status="failed";
        }
    return Status ;    
}

Solution

You had a mix of some synchronous calls from the fs module and some asynchronous and the asynchronous ones were not waiting for your loops so things were going out of sequence.

Since this is a utility stand-alone script (not a server), you can just use the synchronous version of things everywhere and simplify your coding flow. Change fs.readdir() to fs.readdirSync() and fs.writeFile() to fs.writeFileSync().

Also, be sure to declare any variable before using it.

for (let i = 0; i < DirectoriesDHRD.length; i++) {
    let DirectoriesSCENARIO = getDirectories('.\\captures\\ref\\' + DirectoriesDHRD[i]);
    for (let j = 0; j < DirectoriesSCENARIO.length; j++) {
        let dirtestresult = path.join('VisualTests', DirectoriesDHRD[i], DirectoriesSCENARIO[j]);
        let dirref = path.join('captures', 'ref', DirectoriesDHRD[i], DirectoriesSCENARIO[j]);
        let dirtest = path.join('captures', 'test', DirectoriesDHRD[i], DirectoriesSCENARIO[j]);
        if (!fs.existsSync(dirtestresult)) {
            fs.mkdirSync(dirtestresult, { recursive: true });
        }
        let files = fs.readdirSync(dirref);
        let TestResult = "";
        let Status;
        if (files.length == 0) {
            console.log("test skipped or pending");
            TestResult = "skipped/pending";
        } else {
            TestResult = "passed";
            files.forEach(function(file, Status) {

                var filepathref = path.join(dirref, file);
                var filepathtest = path.join(dirtest, file);
                if (fs.existsSync(filepathtest)) {
                    Status = compare(file, filepathref, filepathtest, dirtestresult);
                    if (Status == "failed") {
                        TestResult = "failed";
                    }
                } else {
                    console.log("test missing screenshots");
                    TestResult = "failed";
                }
            });

        }
        switch (TestResult) {
            case 'passed':
                pass++;
                break;
            case 'skipped/pending':
                skip++;
                break;
            case 'failed':
                fail++;
                break;
            default:
                console.log(`error`);
        }
        let Test = {
            name: DirectoriesSCENARIO[j],
            tag: DirectoriesDHRD[i],
            status: TestResult
        };

        let TestJson = JSON.stringify(Test, null, "\t");
        alltests.push(Test);
        console.log(alltests[i]);
        fs.writeFileSync(dirtestresult + "\\test.json", TestJson);
        console.log("File written successfully\n");
    }
    if (i == DirectoriesDHRD.length - 1) {
        let result = JSON.stringify({ pass: pass, fail: fail, skip: skip }, null, "\t");
        fs.writeFileSync(".\\VisualTests\\result.json", result);
        console.log("Result File written successfully\n");
        let jsonresult = JSON.stringify(alltests, null, "\t");
        console.log("///////////////////////");
        console.log(jsonresult);
        fs.writeFileSync(".\\VisualTests\\Tests_results.json", jsonresult);
        console.log("Result File written successfully\n");
    }
}

Note that error handling with the Sync versions is via throwing an exception so if you want to catch those exceptions in order to continue rather than abort, you will need to put appropriate try/catch blocks in whatever scope you’re trying to catch the errors. Right now the code assumes you put a try/catch block at a higher level and catch the error there.

Answered By – jfriend00

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published