I want to post an image to server.But before that I want to make sure that directory is create, before placing an image to a correct folder.The folder that I want to create is year/month/day/[image]. I am able to generate the folder on my local PC, but when I want to apply on the server, an error message is displayed and the folder is not created.I don't know what mistake that I have made, I hope someone can help me solve this problem.
Thank you in advance.
PWD
ERROR
return binding.mkdir(pathModule._makeLong(path), Error: ENOENT: no
such file or directory, mkdir
'/home/eis/development/eis-api-dev/picture/2020/06/01/'
CODE
var storage = multer.diskStorage({
destination: function (req, file, cb) {
///output: home/eis/development/eis-api-dev/picture/2020/06/01/
const dir = path.join(__dirname,_const.IMAGE_FILE_PATH+_const.generateImagePath(null,null,null));
console.log("path:"+dir);
fs.exists(dir,exists =>{
if(!exists){
//mkdirp.sync(dir);
return fs.mkdirSync(dir,{recursive: true},error => cb(error,dir));
}
return cb(null,dir)
});
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
try to create using mkdirp
if (!fs.existsSync(directoryPath)){
mkdirp(directoryPath, function (err) {
if (err) {
console.log("Error Creating Directory "+directoryPath);
}
else {
console.log("Creating Directory "+directoryPath);
}
}
I just have to upgraded latest nodejs version and its worked.
To create a directory asynchronously
const fs = require('fs');
const path = 'newfolder/xyz/';
fs.exists(path, exists => {
if (exists) {
console.log('The directory exists...!!');
}
else {
fs.mkdir(path, { recursive: true }, (error) => {
console.log(error);
if (error)
// print or display your error
else {
return path;
}
});
}
});
Related
I'm currently stuck trying to retrieve a file from file system in order to send it through api to the client. For my backend I'm using express js
I'm using fs library and currently I'm trying to do it with readFile function, but I want to do it without specifying the file name or just the file extension because it will depend from file file will be uploaded from client.
What I tried until now (unsuccessfully) is shown below:
router.get("/info/pic", async (req, res) => {
const file = await fs.readFile("./images/profile/me.*", (err, data) => {
if (err) {
console.log(err); // Error: ENOENT: no such file or directory, open './images/profile/me.*'
return;
}
console.log(data);
});
});
const file = await fs.readFile("./images/profile/*.*", (err, data) => {
if (err) {
console.log(err); // Error: ENOENT: no such file or directory, open './images/profile/*.*'
return;
}
console.log(data);
});
const file = await fs.readFile("./images/profile/*", (err, data) => {
if (err) {
console.log(err); // Error: ENOENT: no such file or directory, open './images/profile/*'
return;
}
console.log(data);
});
If I specify the file name everything works fine, like: fs.readFile("./images/profile/me.jpg". but as I said, I don't know for sure the right extension of that file.
Important info: In that directory there will be only one file!
Please help me!
Thank you in advance!
If there is only one file in the directory, the following loop will have only one iteration:
for await (const file of fs.opendirSync("./images/profile")) {
var image = fs.readFileSync("./images/profile/" + file.name);
...
}
const fs = require('fs');
fs.readdir('./images/profile', function (err, files) {
//handling error
if (err) {
return console.log('err);
}
files.forEach(function (file) {
// Do whatever you want to do with the file
});
});
I want to Use multer function in controller file But the problem is req.body got undefine when I use postman form-data body to upload images This is link to code that how I am using multer Function but I want use it in my controller
how I want to use it as you can see in below code
const multerHelper = require("../helpers/multer_helper");
Documents: async (req, res) => {
console.log(req.body)
if (!req.body.id) {
console.log(req.body)
logger.warn(error.MANDATORY_FIELDS);
return res.status(500).send(error.MANDATORY_FIELDS)
}
try {
multerHelper.createUserImage
let result = error.OK
logger.info(result);
return res.status(200).send(result)
} catch (err) {
logger.warn(err);
console.log(err);
return res.status(500).send(error.SERVER_ERROR)
}
}
but it throws error like req.body undefine
req.body empty image
postman form-data image
Anyone know how to do it
You can use multer functions and objects in only routes not in controller if you want to use it in controller you have to write storage and upload functions in controllers, here I have used multer error handling and I am uploading multiple images
Documents: async (req, res) => {
if (!req.headers.room_id) {
logger.warn(error.MANDATORY_FIELDS);
return res.status(500).send(error.MANDATORY_FIELDS)
}
try {
let storage = multer.diskStorage({
destination: function (req, file, cb) {
let id = req.headers.room_id;
let path = `tmp/daily_gasoline_report/${id}`;
fsextra.mkdirsSync(path);
cb(null, path);
},
filename: function (req, file, cb) {
// console.log(file);
let extArray = file.mimetype.split("/");
let extension = extArray[extArray.length - 1];
cb(null, file.fieldname + '-' + Date.now() + "." + extension);
}
})
var upload = multer({ storage: storage }).array('images', 100);
upload(req, res, function (err) {
if (err) {
console.log(err);
return res.end("Error uploading file.");
} else {
res.end("File has been uploaded");
}
});
let result = error.OK
logger.info(result);
return res.status(200).send(result)
} catch (err) {
logger.warn(err);
console.log(err);
return res.status(500).send(error.SERVER_ERROR)
}
}
Do you have a parser?
How do you parse the data?
Your gonna need to use something that gives you this data something like:
https://www.npmjs.com/package/express-fileupload
this package helps you to parse the form data and the files data itself.
I am trying to get a file from html form and store it in another folder. It's basically cloud function, and I am new to both node.js and firebase so don't know what I am doing wrong. What I manage to do is:
const fileMiddleware = require('express-multipart-file-parser');
app.post("/sendMail", (req, res) => {
const {
fieldname,
filename,
encoding,
mimetype,
buffer,
} = req.files[0];
console.log(req.files[0].originalname);
var fs = require('fs')
var oldPath = req.files[0].originalname;
var newPath = '/functions/'+oldPath;
fs.rename(oldPath, newPath, function (err) {
if (err) throw err
console.log('Successfully renamed - AKA moved!')
});
});
Whenever I try to move file, I got path issues. The error is as follows:
[Error: ENOENT: no such file or directory, rename 'C:\Users\Maisum Abbas\now\functions\sendMail.txt'
> 'C:\functions\sendMail.txt'] {
> errno: -4058,
> code: 'ENOENT',
> syscall: 'rename',
> path: 'C:\\Users\\Maisum Abbas\\now\\functions\\sendMail.txt',
> dest: 'C:\\functions\\sendMail.txt'
> }
Also, this is the path where I want to actually move the file but oldpath is already setup like this.
C:\Users\Maisum Abbas\now\functions\sendMail.txt
Since I needed to attach a file with email, it was causing path issues. I tried it with multer and it works. What I did:
//call libraries here
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, 'resume/');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).single('filetoupload');
app.post("/careerMail", (req, res) => {
const { name } = req.body;
const { email } = req.body;
const { phone } = req.body;
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
});
const dest = 'mymail';
const mailOptions = {
from: email, // Something like: Jane Doe <janedoe#gmail.com>
to: dest,
subject: 'Candidate Application', // email subject
html: `<div>
<strong>From:</strong> ` +
name +
`<br /><br />
<strong>Email:</strong> ` +
email +
`<br /><br />
<strong>Phone:</strong> ` +
phone +
`<br /><br />
</div>
`,// email content in HTML
attachments: [
{
filename: req.files[0].originalname,
content: req.files[0].buffer.toString("base64"),
encoding: "base64"
}
]
and rest of the code...
I suggest rethinking this approach altogether. You won't be able to move files around in a deployed function. The nodejs runtime filesystem doesn't allow any files to be written anywhere in the filesystem, except for os.tmpdir() (which is /tmp on Linux).
If you need to write a file temporarily, you should definitely only use that tmp space. Be aware that files written there occupy memory and should be deleted before the function terminates, or you could leak memory.
You can read files that you deployed with your code, but you should do that through relative paths.
I ran into same problem while moving file. I sort this problem by using a function to get the application root folder and then concatenate rest of the location.
//place this file on application root.
//import where you need to get the root path.
const path = require('path');
module.exports = (function(){
return path.dirname(require.main.filename || process.mainModule.filename);
})();
//taking your case move location.
const rootPath = //require the above module.
const newPath = rootPath + /functions/' +oldPath;
fs.rename(oldPath, newPath, function (err) {
if (err) throw err
console.log('Successfully renamed - AKA moved!')
});
I have the below file upload script in sails
uploadImage: async function (req, res) {
req.file("postImage").upload(
{
dirname: require("path").resolve(sails.config.appPath, "assets/images"),
},
function (err, uploadedFiles) {
if (err) {
return res.serverError(err);
}
if (uploadedFiles.length === 0) {
return res.badRequest("No file was uploaded");
}
var baseUrl = sails.config.custom.baseUrl;
var mediaURI = require("util").format(
"%s/assets/images/%s",
baseUrl,
uploadedFiles[0].fd
);
return res.json({
message: uploadedFiles.length + " file(s) uploaded successfully!",
mediaURI: mediaURI,
});
}
);
},
This successfully upload the image in my assets/images folder
but when i tried opening the image in browser at http://localhost:1337/assets/images/35820a8d-46fa-4a81-bc7b-fc2ca9d07d99.png
It shows not found
I tried http://localhost:1337/images/35820a8d-46fa-4a81-bc7b-fc2ca9d07d99.png also still not found
my policy is
module.exports.policies = {
"*": true,
};
The error is because you upload a file in the ${sails.config.appPath}/assets/images folder that is different from the ${sails.config.appPath}/.tmp/public/images folder, then you can't get access directly from your URL to the assets folder as your-domain/images/an-image.png, to do that you need a controller to download the image where it's stored:
Look at this example how to upload a file using the sails-hook-uploads module:
https://github.com/mikermcneil/ration/blob/master/api/controllers/things/upload-thing.js#L54
And then how to download it:
https://github.com/mikermcneil/ration/blob/master/api/controllers/things/download-photo.js#L50
I have written some middleware for uploading an avatar, like this:
var gm = require('gm'),
mkdirp = require('mkdirp'),
fs = require('fs');
uploadAvatar = function(req, res, next) {
var img, path, user;
if (req.files.avatar_image) {
user = req.user;
img = req.files.avatar_image;
path = __dirname + "/../../public/avatar/" + (user.name.parameterize()) + ".png";
mkdirp.sync(__dirname + "/../../public/avatar/");
fs.createReadStream(img.path).pipe(fs.createWriteStream(path));
gm(path).resize(250, 250).autoOrient().quality(90).write(path, function(err) {
if (err != null) {
req.flash('error', err);
} else {
user.avatar = "/avatar/" + (user.name.parameterize()) + ".png";
user.save(function(err) {
if (err != null) {
req.flash('error', err);
}
next();
});
}
});
} else {
next();
}
};
// Usage
app.post('/upload', ensureAuthenticated, uploadAvatar, handleUpload);
When I now try to upload an image, node crashed with the incredibly helpful error message:
events.js:72
throw er; // Unhandled 'error' event
^
Error: ENOENT, open '/tmp/1126846a248af5c584770b07de649f9b.png'
I have tried copying the file before using gm on it, too. I suspect that express deletes the file before I can even touch it, as a "security".
Can anyone help me here?
EDIT: Full source
First of all copy temp file to your avatar directory, and second make sure that you have permissions on avatar as well as temp directory and files.
As well piping read to write stream is not sync operation, and you will try to pipe straight after initialising read handle, that might lead to some problems.
You need to add events and wait till file get copied:
var complete = function(err) {
if (!err) {
// process your gm
} else {
console.log(err);
}
}
var read = fs.createReadStream(sourcePath);
read.on('error', function(err) {
complete(err);
});
var write = fs.createWriteStream(targetPath);
write.on('error', function(err) {
complete(err);
});
write.on('close', function() {
complete();
});
read.pipe(write);