The following code does not create a new directory, nor does it output any err
const fs = require("fs-extra");
fs.mkdir(dirPath, { recursive: true }, (err) => {
if (err) {
console.log("ERR: When attempting to mkdir", err);
} else {
console.log("MKDIR made " + dirPath);
}
cb(null, dirPath);
});
I would expect the directory to be created... or an error.
When I console.log(err) I find that the value of err is null.
How can I ensure this directory has been created?
Related
I am uploading my files in a directory using Multer.
I want to download those same files which I have uploaded as I am displaying them in the form of a table on the template with each file having a download option. Here's my code:
Express.js
router.get('/downloadfile', (req, res, next) => {
var options = {
root: path.join(__dirname, './uploads'), //all my files are saved in uploads folder
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
}
var fileName = req.query.id3
res.sendFile(fileName, options, function (err) {
if (!err)
{
console.log('File sent successfully');
}
else
{
console.log('Error occurred while sending file.' + err.message)
}
})
});
Angular
onDownloadFiles(i: any)
{
this.fileToDownload = i;
console.log(this.fileToDownload);
const params = new HttpParams().set('id3', this.fileToDownload);
this.http.get('http://localhost:3000/downloadfile', {params})
.pipe(map(responseData => { return responseData; }))
.subscribe(response => {
console.log(response);
})
}
Here is the error while clicking on the download button.
TypeError: path argument is required to res.sendFile
Well, you can use modern try-catch methods when you're programming with asynchronous javascript rather than using conventional if-else statements to log errors.
Secondly, instead of using a callback function inside res.sendFile it is better to check whether the file exists and then send it.
Here's a sample code.
module.exports.getExe = async (req, res) => {
try {
const file = getExeFilePath(req.params.filename)
if (!fs.existsSync(file.path)) {
res.status(200).json({ 'status': false, 'result': 'File not found!' })
} else {
res.setHeader('Content-disposition', 'attachment; filename=' + file.name);
//filename is the name which client will see. Don't put full path here.
res.setHeader('Content-type', file.type);
var sendFile = fs.createReadStream(file.path);
sendFile.pipe(res);
}
} catch (error) {
console.log(error)
res.status(200).json({ 'status': false, 'result': 'Failed!' });
}
}
I'm trying to create a photo album app in MEVN.
The req.body.ALBUM will become the folder's name then for the req.body.DESCRIPTION is just its description.
What my code accomplished was just it can create the folder but it creates an undefined folder then save the images inside it.
NOTE: I tried to create an empty folder and change the directory to my sample folder and it can successfully save the images there.
Here is my full code that can only create the folder but not saves the images inside it rather it saves the image in the undefined folder.
router.post('/album', (req, res) => {
let sql = "INSERT INTO GALLERY SET ALBUM = ?, DESCRIPTION = ?";
let body = [req.body.ALBUM, req.body.DESCRIPTION]
myDB.query(sql, body, (error, results) => {
if (error) {
console.log(error);
} else {
let directory = `C:\\Users\\user\\Desktop\\project\\myproject\\public\\${req.body.ALBUM}`;
fse.mkdirp(directory, err => {
if (err) {
console.log(err);
} else {
console.log("Success");
}
});
const myStorage = multer.diskStorage({
destination: directory,
filename: function (req, file, cb) {
cb(null, file.originalname + path.extname(file.originalname))
}
});
const myUploads = multer({
storage: myStorage, limits: {
//10 Million
fileSize: 10e6
}
}).array('files', 15);
if (fse.exists(directory)) {
myUploads(req, res, (error) => {
if (error) {
console.log(error);
} else {
res.send("Success")
}
});
}
else {
console.log(false);
}
}
})
})
When it comes to this part, the req.body.ALBUM becomes undefined therefore the images were saved inside undefined folder.
const myStorage = multer.diskStorage({
destination: directory,
filename: function (req, file, cb) {
cb(null, file.originalname + path.extname(file.originalname))
}
});
try this
fse.mkdirp(directory, err => {
if (err) {
console.log(err);
} else {
const myStorage = multer.diskStorage({
destination: directory,
filename: function (req, file, cb) {
cb(null, file.originalname + path.extname(file.originalname))
}
});
}
});
Here you are waiting for first operation to complete
if (sess.username) {
var form = new formidable.IncomingForm();
form.multiples = true;
form.uploadDir = __dirname + "/data";
form.parse(req, function (err, fields, files) {
if (fields.title.length < 120 || fields.content.length < 1000000) {
var articleData = new articleModel({
title: fields.title,
content: fields.content,
created_at: Date.now()
});
articleData.save(function (err) {
console.log('saved');
});
form.on('error', function (err) {
console.log('An error has occured: \n' + err);
});
}
else {
res.render('failed', {
message: 'Too much characters.'
});
}
});
res.redirect('/admin');
}
I was trying with this code but i got error like this:
Error: ENOENT: no such file or directory, open
'C:\Users\Użytkownik\Documents\GitHub\CFBlog\controllers\admin\data\upload_c2aff6d1c5930dd655caa436890aaf03'
at Error (native)
Seems like you don't have data/ folder in your __dirname.
Formidable just can't create file in folder that doesn't exist.
I have a dashboard that generates JSON data and saves it as a .json file. This was initially written in PHP but for various reasons we have re-written the application in node. The code below takes the post data and then should check to see if the file exists then if it does update it if not it should create the file and directory.
However it only seems to create the first file and I cannot fathom why it doesn't create the subsequent files as this post route is called once for each post.
the post method looks like this
$.ajax({
type : "POST",
url : '/save/',
dataType : 'json',
data : {
category : settings.category_id,
name : settings.campaignId,
json : JSON.stringify(settings)
}
});
I have debugged and when called all the correct file paths are passed but its almost as if the file isn't being written with the data.
During debugging using node-inspector and nodemon the code loops through all the requested new file names and gives me the error code ENOENT, so it should then follow the create file path.
If you know anything about node and the file system module and feel like helping me out that would be amazing even if it's just pointing me in the direction of some more tutorials, ... anything would be great!
-
'use strict'
const fs = require('fs');
const path = require('path');
const express = require('express');
const router = express.Router();
/* Save Data */
router.post('/', function(req, res) {
if (!(req.body.json && req.body.name && req.body.category)) {
res.sendStatus(400);
return;
}
let dir = 'public/savedData/' + req.body.category;
let filepath = dir + '/' + req.body.name + '.json';
fs.access(filepath, function(error) {
console.log(filepath);
console.log(error.code);
if (error) {
if (error.code == 'ENOENT') {
console.log(error.code);
//debugger;
// Create file since it doesn't exist
createFile(req, res, filepath);
} else {
//debugger;
console.log('access error:', error);
res.sendStatus(500);
}
} else {
//debugger;
// Update file since it already exists
updateFile(req, res, filepath);
}
});
});
function createFile(req, res, filepath) {
try {
let json = JSON.parse(req.body.json);
let output = JSON.stringify([json], null, 4);
fs.mkdir(path.dirname(filepath), function(error) {
if (error) {
if (error.code == 'EEXIST') {
updateFile(req, res, filepath);
} else {
res.sendStatus(500);
console.log('create file error :', error);
}
} else {
fs.writeFile(filepath, output, function(error) {
if (error) {
res.sendStatus(500);
console.log('write file error :', error);
} else {
res.sendStatus(200);
console.log('Data successfully saved');
}
});
}
});
} catch (error) {
res.sendStatus(500);
console.log(error);
}
}
function updateFile(req, res, filepath) {
try {
fs.readFile(filepath, 'utf-8', function(error, data) {
if (error) {
res.sendStatus(500);
console.log('update error:', error);
} else {
try {
let newJSON = JSON.parse(req.body.json);
let jsonArray = JSON.parse(data);
let output;
jsonArray.push(newJSON);
output = JSON.stringify(jsonArray, null, 4);
fs.writeFile(filepath, output, function(error) {
if (error) {
res.sendStatus(500);
console.log(error);
} else {
res.sendStatus(200);
console.log('Data successfully saved');
}
});
} catch (error) {
res.sendStatus(500);
console.log(error);
}
}
});
} catch (error) {
res.sendStatus(500);
console.log(error);
}
}
module.exports = router;
Instead of checking if the file exists, you should try to write with flags wx, which creates a file but fails if it does already exist. That way you won't be subjecting yourself to race conditions. I would also suggest the package mkdirp, which does not emit an error if the directory already exists.
router.post('/', (req, res) => {
if (!(req.body.json && req.body.name && req.body.category)) {
res.sendStatus(400);
return;
}
const dirpath = `public/savedData/${req.body.category}`;
const filepath = `${dirpath}/${req.body.name}.json`;
mkdirp(dirpath, err => {
if (err) {
console.error('mkdirp failed', err);
return res.sendStatus(500);
}
const output = JSON.stringify([JSON.parse(req.body.json)]);
fs.writeFile(filepath, output, { flags: 'wx' }, err => {
if (err) {
console.error('writeFile failed', err);
return res.sendStatus(500);
}
console.log('Data successfully saved');
res.sendStatus(200);
});
);
});
Make sure you sanitize the req.body.name and req.body.category parameters, since you could expose your filesystem to unintentional overwrites.
Thanks to #Iso this is my solution
router.post('/', (req, res) => {
if (!(req.body.json && req.body.name && req.body.category)) {
res.sendStatus(400);
return;
}
const dirpath = 'public/savedData/' + req.body.category;
const filepath = dirpath + '/' + req.body.name + '.json';
mkdirp(dirpath, err => {
if (err) {
console.error('mkdirp failed', err);
return res.sendStatus(500);
}
const output = JSON.stringify([
JSON.parse(req.body.json)
]);
fs.readFile(filepath, 'utf-8', function(error, data) {
if(error) {
fs.writeFile(filepath, output, err => {
if (err) {
console.error('writeFile failed', err);
return res.sendStatus(500);
}
console.log('Data successfully saved');
res.sendStatus(200);
});
} else {
let newJSON = JSON.parse(req.body.json);
let jsonArray = JSON.parse(data);
let output;
jsonArray.push(newJSON);
output = JSON.stringify(jsonArray, null, 4);
fs.writeFile(filepath, output, err => {
if (err) {
console.error('writeFile failed', err);
return res.sendStatus(500);
}
console.log('Data successfully saved');
res.sendStatus(200);
});
}
});
});
});
What I want to do is to output the content of all the files in a folder:
const fs = require('fs')
, input = process.argv[2]
fs.readdir(__dirname + `/${input}/`, (err, files) => {
if (err) {
console.log(err)
return
}
files.forEach((file) => {
console.log(file)
fs.readFile(file, 'utf8', (err, data) => {
console.log(data)
})
})
})
But I'm puzzled console.log(file) do output the file names:
alex#alex-K43U:~/node/m2n/bin$ node index4.js folder
test.txt
test2.txt
But console.log(data) returns undefined:
alex#alex-K43U:~/node/m2n/bin$ node index4.js folder
undefined
undefined
What's happening here?
EDIT:
Maybe there's a problem with __dirname? This is my project structure:
You need to pass full path to your filenames:
fs.readFile(__dirname + `/${input}/` + file, 'utf8', (err, data) => {
And I would recommend you to log errors so you will know next time what is happening wrong:
fs.readFile(__dirname + `/${input}/` + file, 'utf8', (err, data) => {
if (err) {
console.log(err)
}
console.log(data)
})