Ash
Ash

Reputation: 896

Node.js fs.WriteStream behaving strangely

I was expecting the code below to print out

Finished writing GB translations
Finished writing DE translations
Finished writing US translations

But instead it prints out

Finished writing DE translations
Finished writing DE translations
Finished writing DE translations

Code:

try {
    fs.mkdirSync('./locales');
} catch(e) {
    console.log('Info: Locales directory already exists');
}

jsonDefs = {
             GB: {"Item does not exist": "Item does not exist"},
             DE: {"Item does not exist": "Artikel existiert nicht"}, 
             US: {"Item does not exist": "Item does naaht exist"}
           };

for(language in jsonDefs){
    const fileName = `${language.toLowerCase()}.json`;
    const writeStream = fs.createWriteStream(`./locales/${fileName}`);
    writeStream.on('finish', function(){ console.log(`Finished writing ${language} translations`); });
    writeStream.on('error', function(err){
      console.log(`Error writing to ${fileName}: ${err}`);
    });
    writeStream.write(JSON.stringify(jsonDefs[language]), () => writeStream.end());
}

Other than that though it seems to work fine, everything is written to gb.json, de.json and us.json as expected. Why is this?

Upvotes: 0

Views: 31

Answers (1)

Explosion Pills
Explosion Pills

Reputation: 191729

language is overwritten in the for loop each time, but the .on('finish' executes asynchronously. So language = 'DE' effectively occurs first, then all of the 'finish' events occur so it'll print out whatever 'language' was set to last.

There are a lot of ways to tackle this, but the easiest / one that requires the least amount of changes is to just use let, as in:

for (let language in jsonDefs) {

This will scope language for each iteration of the loop.

Upvotes: 1

Related Questions