directory is not creating - javascript

Am trying to create a directory with subfolders in my application. The new request will create folders only if the parent folder is already there but not creating if root folder is not there.
import { mkdir } from 'fs';
mkdir(join(__dirname, '../folder_to_create_directory/', req.body.path), (err) => {
if (err) {
return "error";
}
return "success"
});
The req.body.path is a path string eg: test/folder/subfolder. The code will work only if we create the "test" folder manually (it is not returning "success" message too even though the directory is being created). IF the test folder is not there then the directory is not creating.
expected output:-
folder_to_create_directory/test/folder/subfolder

You can use fs library to work with a file system.
For nested dirs:
var fs = require('fs');
var dir = join(__dirname, '../folder_to_create_directory/', req.body.path);
if (!fs.existsSync(dir)){
fs.mkdirSync(dir, { recursive: true });
}
Or, for individual dirs:
var fs = require('fs');
var dir = join(__dirname, '../folder_to_create_directory/', req.body.path);
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}

you are missing an option "{recursive: true}". Try this example:
const { mkdir } = require("fs");
const {join} = require('path')
const path = join(__dirname, "../folder_to_create_directory", 'test/folder/subfolder')
mkdir(path, { recursive: true }, (err) => {
if (err) {
return "error";
}
return "success";
});

Related

How to apply a function from node package to all the files in a directory?

I've installed mammoth.js module which converts docx to html. I can use it with a single file.
How do I use the same module for all the files in a specific folder? I'm trying to save an output html files while keeping the original name (not the extension, of course). Probably I have to require some other packages...
The code below is for a single file from the desired directory:
var mammoth = require("mammoth");
mammoth.convertToHtml({path: "input/first.docx"}).then(function (resultObject) {
console.log('mammoth result', resultObject.value);
});
The system is win64
Something like this should work
const fs = require('fs')
const path = require('path')
const mammoth = require('mammoth')
fs.readdir('input/', (err, files) => {
files.forEach(file => {
if (path.extname(file) === '.docx') {
// If its a docx file
mammoth
.convertToHtml({ path: `input/${file}` })
.then(function(resultObject) {
// Now get the basename of the filename
const filename = path.basename(file)
// Replace output/ with where you want the file
fs.writeFile(`output/${filename}.html`, resultObject.value, function (err) {
if (err) return console.log(err);
});
})
}
})
})

Write file to directory then zip directory

I am trying to write a file to a directory templates then stream a zip with the content that was written. However, the when the zip file is returned it says Failed - Network Error which is due to the fs.writeFile in the controller. If i remove the WriteFile stream then the zipping works fine. My question is how do i first write the file then run the zip. There seems to be something synchronous happening with the archiving and file writing of typeArrayString.
Controller:
exports.download_one_feed = function(req, res, next) {
Feed.findOne({'name': req.params.id})
.exec(function(err, dbfeeds){
if(err){
res.send('get error has occured in routes/feeds.js');
} else {
const feedArray = dbfeeds.feed.data;
// write file
// get from db collection & write file to download
const typeArrayString = JSON.stringify(feedArray);
let type = 'b'; // test only
fs.writeFile(path.join(appDir, 'templates/' + type + '/template.json'), typeArrayString, (err) => {
if (err) throw err;
console.log('Saved!');
})
archiverService.FileArchiver(feedArray, res);
}
})
};
Archive Service
const archiver = require('archiver')
const zip = archiver('zip')
const path = require('path')
const fs = require('fs')
const appDir = path.dirname(require.main.filename)
exports.FileArchiver = function (feedArray, res) {
// const app = this.app;
const uploadsDir = path.join(appDir, '/uploads/');
const templatesDir = path.join(appDir, '/templates/');
const extensions = [".jpg", ".png", ".svg"];
let imageArray = [];
const feedArrayObject = JSON.parse(feedArrayString);
feedArrayObject.forEach(function(x){iterate(x)}); // grab image names from object
imageArray = uniq_fast(imageArray); // remove duplicates
// zip images
for (let i = 0; i < imageArray.length; i++) {
console.log(imageArray[i])
const filePath = path.join(uploadsDir, imageArray[i]);
zip.append(fs.createReadStream(filePath), { name: 'images/'+imageArray[i] });
}
res.attachment('download.zip');
zip.pipe(res);
// zip template directory
console.log(templatesDir)
zip.directory(templatesDir, false);
zip.on('error', (err) => { throw err; });
zip.finalize();
return this;
}
Instead of writing the file then zipping the directory, i used zip.append to override the old file in the directory.

NodeJS - Send converted file to client side to download

GOAL: Allow the user to download a PDF
Background: The below code generates a car.pdf file and stores it into the main project's directory when localhost:3000/ is loaded. This is great because I want to find a Car by id in the database, generate a handlebars template, pass the data from Car into it, and generate a PDF from the compiled HTML
Issue: Instead of saving the PDF to the main project's directory, I want it to download to the user's computer.
How can I do this?
Here is my code. I am using the NPM package: html-pdf
helpers/export-helper.js
const fs = require('fs');
const pdf = require('html-pdf');
const Handlebars = require('handlebars');
const { Car } = require('./../models/car');
var writePDF = (res) => {
Car.findById({_id: '58857e256b639400110897af'})
.then((car) => {
var source = fs.readFileSync(__dirname + '/templates/car.handlebars', 'utf8');
var template = Handlebars.compile(source);
var file = template(car);
pdf.create(file, { format: 'Letter' })
.toFile('./car.pdf', (err, res) => {
if (err) return console.log(err);
console.log(res); // { filename: '/app/businesscard.pdf' }
});
})
.catch((errors) => {
console.log(errors);
});
};
module.exports = { writePDF };
routes/home.js
const express = require('express');
const router = express.Router();
const { writePDF } = require('./../helpers/export-helpers');
router.get('/', (req, res) => {
writePDF();
});
module.exports = router;
You should use res.download for this. Like so
router.get('/', (req, res) => {
res.download('car.pdf');
});
https://expressjs.com/en/api.html#res.download
You have to pipe the created pdf with response to client side.

Copy a source file to another destination in Nodejs

I'm trying to copy an image from a folder to another using fs-extra module .
var fse = require('fs-extra');
function copyimage() {
fse.copy('mainisp.jpg', './test', function (err) {
if (err)
return console.error(err)
});
}
This is my directory
and this is the error I get all the time:
Error {errno: -4058, code: "ENOENT", syscall: "lstat", path:
"E:\mainisp.jpg", message: "ENOENT: no such file or directory, lstat
'E:\mainisp.jpg'"}
and by changing destination to ./test/ I get this error
Error {errno: -4058, code: "ENOENT", syscall: "lstat", path:
"E:\Development\Node apps\Node softwares\Digital_library\mainisp.jpg",
message: "ENOENT: no such file or directory, lstat 'E:\Devel…
apps\Node softwares\Digital_library\mainisp.jpg'"}
Note: I'm not testing this in browser. It's an Nwjs app and the pics of error attached are from Nwjs console.
You can do this using the native fs module easily using streams.
const fs = require('fs');
const path = require('path');
let filename = 'mainisp.jpg';
let src = path.join(__dirname, filename);
let destDir = path.join(__dirname, 'test');
fs.access(destDir, (err) => {
if(err)
fs.mkdirSync(destDir);
copyFile(src, path.join(destDir, filename));
});
function copyFile(src, dest) {
let readStream = fs.createReadStream(src);
readStream.once('error', (err) => {
console.log(err);
});
readStream.once('end', () => {
console.log('done copying');
});
readStream.pipe(fs.createWriteStream(dest));
}
Try:
var fs = require('fs-extra');
fs.copySync(path.resolve(__dirname,'./mainisp.jpg'), './test/mainisp.jpg');
As you can see in the error message, you're trying to read the file from E:\mainisp.jpg instead of the current directory.
You also need to specify the target path with the file, not only the destination folder.
Try:
const fs = require('fs');
fs.copyFileSync(src, dest);

nodejs load file

I want to load test.txt with nodejs.
var fs = require('fs');
fs.readFile('./test.txt', function (err, data) {
if (err) {
throw err;
}
console.log(data);
});
The path of the server is C:\server\test\server.js. The test.txt is located in the same directory, but I get this error: Error: ENOENT, no such file or directory 'C:\Users\User\test.txt'
Paths in Node are resolved relatively to the current working directory. Prefix your path with __dirname to resolve the path to the location of your Node script.
var fs = require('fs');
fs.readFile( __dirname + '/test.txt', function (err, data) {
if (err) {
throw err;
}
console.log(data.toString());
});
With Node 0.12, it's possible to do this synchronously now:
var fs = require('fs');
var path = require('path');
// Buffer mydata
var BUFFER = bufferFile('../test.txt');
function bufferFile(relPath) {
return fs.readFileSync(path.join(__dirname, relPath)); // zzzz....
}
fs is the file system. readFileSync() returns a Buffer, or string if you ask.
fs correctly assumes relative paths are a security issue. path is a work-around.
To load as a string, specify the encoding:
return fs.readFileSync(path,{ encoding: 'utf8' });
You should use __dirname to get the directory name the file is located instead of the current working directory:
fs.readFile(__dirname + "/test.txt", ...);
Use path and fs:
const fs = require("fs");
const pth = require("path");
Sync:
let data = fs.readFileSync(pth.join(__dirname,"file.txt"));
console.log(data + "");
A-Sync:
fs.readFile(pth.join(__dirname,"file.txt"), (err, data) => {
console.log(data + "");
});
And that; If you need to read the file continuously and send it to the client and the file size is not large, you may be able to keep a copy of it:
const exp = require("express");
const app = exp();
const fs = require("fs");
const pth = require("path");
let file = "";
app.get("/file", (q, r) => {
if (file === "")
file = fs.readFileSync(pth.join(__dirname,"file.txt")) + "";
r.writeHead(200, { "Content-Type": "text/plain" });
r.write(file);
r.end();
});
so if it is in the same directory just do this
fs.readFile(__dirname+'/foo.txt',function(e,d){console.log(d)})
If it's in same directory it should work. I have tested with the same code, with a file name.txt and it's working fine:
var fs = require('fs');
fs.readFile('./test.txt', function (err, data) {
if (err) {
throw err;
}
console.log(data.toString());
});

Categories