haliofin
haliofin

Reputation: 11

Node.js fs.appendFile if string doesn't exist in the text file

Please looking for suggestions for the best way to append to a text file if the line in the text file does not exist?

For example, file.txt looks like this:

Aimee Kestenberg
ALLSAINTS
14th & Union
3.1 PHILLIP LIM
Champion
Botkier
CHRISTIAN LAURIER
Christopher Kon
Co-Lab
Day & Mood

For example if var x = "Aimee Kestenberg"
Need to add x to file.txt if x does not exist.

The text file would not be too big, around 100-200 lines at most as it grows.
Would I need to read the text file into an array and split on new line?
Then loop through the array and check if it is equal to x?
Then fs.appendFile if x is not in the array?

Currently I'm using fs.appendFile to add all x to the text file.
But the goal is to only add x if it doesn't already exist in the text file.

fs.appendFile('file.txt', '\n' + x, (err) => {
   if (err) throw err;
});

Can anyone please help what the code would look like for reading in the text file and looping through it? Or is there a better way of doing this will built in functions?

Upvotes: 0

Views: 2052

Answers (2)

soimon
soimon

Reputation: 2580

This method returns a Promise that will tell whether a file contains a given line. Note that it is case sensitive.

import { readFile } from "fs/promises";

const containsLine = (path, line) =>
  new Promise(async (resolve) => {
    const data = await readFile(path);
    const lines = data.toString().split(/\r?\n/);
    resolve(lines.includes(line));
});

You can then wrap your own code like this to have a generic asynchronous function:

import { appendFile } from "fs/promises";

async function appendLineIfLacking(path, line) {
  if (await containsLine(path, line))
    await appendFile(path, "\n" + line );
}

Upvotes: 2

Zac Anger
Zac Anger

Reputation: 7767

Your idea on iterating through the lines is a good one. You could also skip the splitting and iteration and check through the whole file:

const inputData = fs.readfileSync('file.txt').toString()

itemsToAppend.forEach((item) => {
  const line = `${item}\n`
  if (!inputData.includes(line)) {
    fs.appendFile('file.txt', line, (err) => {
      if (err) throw err
    })
  }
})

You could also get unique lines and then re-write the whole file (I'm using the sync methods here for brevity but the async versions would work too):

const inputData = fs.readfileSync('file.txt').toString().split('\n')
const newFile = [...new Set([...myNewLines, ...inputData])].join('\n')
fs.writeFileSync('file.txt', newFile)

Upvotes: 1

Related Questions