Ionut Eugen
Ionut Eugen

Reputation: 501

fs.WriteFile launches callback before actually writing the file

I have the following express request callback

zip.addLocalFolder(`/path/to/folder`, `./`);
var data = zip.toBuffer();
fs.writeFile(`path/to/download.zip`,data,function (err) {
    if (err) return console.log(err);
    res.download(`path/to/download.zip`)
});

The fs.writeFile seems to be writing the file after calling the callback function.

Edit: the file is being written successfully. It is the fact that it is being written after I do res.download() that causes the error

If I call res.download() in a setTimeout, of 1 second, the execution ends successfully.

I get this error:

ENOENT: no such file or directory, stat 'path/to/download.zip`

Changing the code to

zip.addLocalFolder(`/path/to/folder`, `./`);
var data = zip.toBuffer();
fs.writeFileSync(`path/to/download.zip`,data);
res.download(`path/to/download.zip`);

has the same effect.

The library I use, adm-zip, has a method for writing the zip file, and working with that has the very same effect.

Is there something I'm missing ?

Upvotes: 2

Views: 513

Answers (1)

Artem Arkhipov
Artem Arkhipov

Reputation: 7465

The issue here is that native file writing methods in nodejs will fail if the selected folder does not exist. So before writing to path/to/folder/download.zip you need to make sure that all these folders path/to/folder already exist.

There are few methods of how achieve that. For example the fs.mkdir method available from Node v10.12

fs.mkdir('/path/to/folder', { recursive: true }, (err) => {
  if (err) throw err;
  ... your write file code here
});

In the example above, node will firstly create all the folders in the path (see the recursive:true option) and then you can write file there.

Important note:

If you are sure, that all directories exist, then the issue is the wrong path passed to the method. Consider using the global __dirname variable in order to resolve correct path to the directory of your script file. Also you may use ./ prefix in path if the path should be relative to the place where app was executed.

Upvotes: 1

Related Questions