Home > Back-end >  How to write multiple lines to a text file in a loop?
How to write multiple lines to a text file in a loop?

Time:06-23

Within a javascript function, I'm taking in a list of events and for each event, I would like to write text to a file. I have provided the correct

// Code within another function
events.map(event => {
        const start = event.start.dateTime || event.start.date;
        const end = event.end.dateTime || event.end.date;
        outputMonthlySessions(`${event.summary}: ${start} - ${end} \n`);
      });
// Function to write to file called sessions located at FILE_PATH
function outputMonthlySessions(content) {
  fs.writeFile(SESSIONS_PATH, content, err => {
    if (err) {
      console.error(err)
    }
  });
}

When I run the function containing that loop, I only get 1 event printed on the SESSIONS text file, but I should be printing 10. That tells me something is wrong with the loop or how I'm using writeFile. I suspect it's something to do with async but then not sure how to format my loop to make it work. Any help would be appreciated!

CodePudding user response:

According to the documentation for fs.writeFile():

Asynchronously writes data to a file, replacing the file if it already exists.
...
It is unsafe to use filehandle.writeFile() multiple times on the same file without waiting for the promise to be resolved (or rejected).

You are overwriting the file each iteration by calling writeFile every time, possibly before the promise is resolved. Instead, I think the simplest approach is to write your text to an intermediate object data (<string> | <Buffer> | <TypedArray> | <DataView> | <Object>) and then filehandle.writeFile(data) at the end.

CodePudding user response:

Use fsPromises.appendFile to append to the file each time instead of overwriting it every time:

./main.mjs:

import {appendFile, readFile} from 'fs/promises';

const SESSIONS_PATH = './sessions_data';

// Append to the file instead of overwriting the entire file
const outputMonthlySessions = (content) => appendFile(SESSIONS_PATH, content);

async function main () {
  const start = 'now';
  const end = 'later';

  const events = [
    {
      summary: 'first',
      start: { date: start },
      end: { dateTime: end },
    },
    {
      summary: 'second',
      start: { dateTime: start },
      end: { date: end },
    },
  ];

  for (const event of events) {
    const start = event.start.dateTime || event.start.date;
    const end = event.end.dateTime || event.end.date;
    await outputMonthlySessions(`${event.summary}: ${start} - ${end} \n`); /*
    ^^^^^
    Await the promise before continuing to the next loop iteration */
  }

  const text = await readFile(SESSIONS_PATH, {encoding: 'utf8'});
  console.log(text.split('\n'));
}

main();

In the terminal:

so-72718707 % node --version  
v16.15.1

so-72718707 % node main.mjs    
[ 'first: now - later ', 'second: now - later ', '' ]
  • Related