javascriptnode.jsfsinquirerinquirerjs

How can I run a command once fs is done writing to a file?


Here is the code in question:

        const scriptFiles = fs.readdirSync(scriptsPath)
            .filter(file => file.endsWith(".sql"));

        for (const file of scriptFiles) {

            var data = fs.readFileSync(`${scriptsPath}/${file}`, 'utf8');
            fs.appendFile(`${scriptsPath}/Hotfix.sql`, data.toString() + "\n", (err) => {
                if (err) throw new Error(err)
                console.log('Appending ' + file + '...')
            })

            process.stdout.cursorTo(0);
        }

        console.log(`start ${scriptsPath}/Hotfix.sql`)
        exec(`start ${scriptsPath}/Hotfix.sql`)

The problem that I'm running into is that it is attempting to open/start scriptsPath/Hotfix.sql before anything has been appended to the file. For example, here is the output from the console.log()s I've added to the script:

start scriptsPath/Hotfix.sql
Appending file1.sql...    
Appending file2.sql...

is there a way I can have the script wait until the for loop has completed before attempting to execute the command?


Solution

  • Replace the appendFile() asynchronous method with the appendFileSync() synchronous method so that code waits until the loop has completed.

    const scriptFiles = fs.readdirSync(scriptsPath)
      .filter(file => file.endsWith(".sql"));
    
    for (const file of scriptFiles) {
    
      var data = fs.readFileSync(`${scriptsPath}/${file}`, 'utf8');
      fs.appendFileSync(`${scriptsPath}/Hotfix.sql`, data.toString() + "\n");
    
      process.stdout.cursorTo(0);
    }
    
    console.log(`start ${scriptsPath}/Hotfix.sql`)
    exec(`start ${scriptsPath}/Hotfix.sql`)