Adam Matan
Adam Matan

Reputation: 136141

Node.js: fs.readdir does not return a file written by fs.writeFile

My app

A simple Node.js http server which creates files in a given directory by calling POST /deploy. After the file is written, I want to list all the files in that directory using console.log.

For creating files (POST /deploy), I call:

fs.writeFile(filename, content, 'utf8', callback(null, {'newFile': filename})); 

The callback writes the HTTP response and lists the files using:

fs.readdir(some_directory, (err, files) => {
    files.forEach(file => {
        console.log(file);
        // Do something with the file
    }
}

My problem

The new file is not listed in the callback. Only after I call deploy again, the previous file is listed. For example, if I create files a and b using /deploy consecutively, a is listed only when b is created and b is not listed until I make another call.

I assume the file is not closed when the callback is called, so that only later calls to fs.readdir see the file, after it has been closed.

How can I call the callback function only after the file is properly closed and can be listed using fs.readdir?

What have I tried

Upvotes: 2

Views: 699

Answers (1)

rsp
rsp

Reputation: 111278

I think this is your problem:

fs.writeFile(filename, content, 'utf8', callback(null, {'newFile': filename})); 

In the code above you run the callback immediately, without waiting for the operation to finish. It would work only if your call to callback(null, {'newFile': filename}) actually returned a function to call as a callback, which I doubt it does.

This may help:

fs.writeFile(filename, content, 'utf8', () => callback(null, {'newFile': filename})); 

because here the callback() will be called after the write operation finishes. But this is still not enough because you need to handle errors:

fs.writeFile(filename, content, 'utf8', (err) => {
  if (err) {
    // handle possible errors
  } else {
    callback(null, {'newFile': filename});
  }
});

e.g. if your callback can take error as the first argument you could do:

fs.writeFile(filename, content, 'utf8', (err) => {
  if (err) {
    callback(err);
  } else {
    callback(null, {'newFile': filename});
  }
});

or returning early you can avoid else:

fs.writeFile(filename, content, 'utf8', (err) => {
  if (err) {
    return callback(err);
  }
  callback(null, {'newFile': filename});
});

Upvotes: 3

Related Questions