Node JS - no such file or directory filesystem module - node.js

I'm trying to use an email template while sending emails. here's my project structure.
project-name
client
server
email-templates
confirm-email.html
controllers
accounts.js (currently here)
I am reading the template file like so.
fs.readFile('../email-templates/confirm-email.html', async (error, html) => {
// do some stuff
})
I think have entered a correct path. but still I get an error.
Error: ENOENT: no such file or directory
I have checked other questions on SO. but they are using the variable __dirname because I am using ES6 modules I don't have access to that variable.
// package.json
"type": "module",
any suggestions ?

Try to use path module to resolve the absolute path the file when you are trying to access the file.
fs.readFile(path.resolve(__dirname, '../email-templates/confirm-email.html'), function(err, html) {// do some stuff})

I don't have access to __dirname because I'm using ES6 modules. I've used path.resolve() instead which fixed the error.
fs.readFile(
path.join(path.resolve(), 'email-templates', 'confirm-email.html'),
'utf8',
(error, html) => {
// do some stuff
}
);
to get access of the __dirname variable when can do:
const __dirname = path.resolve();

Related

How can I allow a user to download a file from a link in express?

I have a function that allows you to create a folder in the directory where the server is located, and upload files there
And I'm trying to access them via a direct link, like this
http://localhost:5000/attachments/1618413024408--1.jpg
Because, the file is located here
But why can't I access it?
Cannot GET /attachments/1618413024408--1.jpg
Express itself provides an easy to use implementation for this express.static(root, [options]).
Simply add this add the right position in your code:
app.use('/attachments', express.static(path.join(__dirname, 'attachments')))
Make sure that path.join(__dirname, 'attachments') points to the right directory (with a simple console.log) otherwise just adjust it.
Documentation: https://expressjs.com/en/starter/static-files.html
try to use express function sendFile
https://expressjs.com/en/api.html#res.sendFile
something like this
app.use('/attachments/:filename', (req, res) => {
const myIms = <path to directory>
const filePath = myIms + '/attachments/' + req.filename
res.sendFile(filePath, {
headers: {
'Content-Type': 'image/jpg'
}
})
})
or express download function https://expressjs.com/en/api.html#res.download

Generate static HTML files from ejs templates

OK, so I have my basic nodejs website up and running. It's all working and runs through a node server - using my basic-node-site
It uses ejs as the templating engine.
I'd like to release these templates as a static website. So all generated locally and it exports all my pages to static HTML files that I can publish on my basic hosting platform. no server side technology required.
I've had a look at jade, but it required me to change the templating and the structure.
Is there any tool out there that just publishes my current setup to a folder with all the generated html files??
Thanks for any help. It's appreciated.
As long as you have the EJS npm package installed you can compile it.
var fs = require('fs'),
ejs = require("ejs");
function ejs2html(path, information) {
fs.readFile(path, 'utf8', function (err, data) {
if (err) { console.log(err); return false; }
var ejs_string = data,
template = ejs.compile(ejs_string),
html = template(information);
fs.writeFile(path + '.html', html, function(err) {
if(err) { console.log(err); return false }
return true;
});
});
}
ejs2html(__dirname+"/index.ejs")
Path: the location of the file, include __dirname or it wont work
Information: the information to be compiled like {users: ['bill','bob']} (optional)
EJS
Reading file in NodeJS
Edit
I made the code work and tested it, the ejs file will be compiled and written to the same directory with .html appended to the end.

Use Cordova's Filetransfer plugin with express/blob storage

I am using Typescript and Cordova 4.0.
I have the following sample code:
uploadImages(imageUris: Array<string>): any {
var fileTransfer = new FileTransfer();
for (var i = 0; i < imageUris.length; i++) {
fileTransfer.upload(imageUris[i], encodeURI('http://3187cf3.ngrok.com/test/photos'), (success) => {
alert('success');
}, (err) => {
alert('error');
});
}
}
This corresponds to an express route:
var router = express.Router(),
test = test.controller;
router
.post('/test/photos', bind(test.uploadPhotos, test));
Which corresponds to a controller method:
uploadPhotos(req: express.Request, res: express.Response) {
console.log(req);
}
I can't seem to figure out how to, inside of my controller, grab the "file" or image I'm posting to my server using Filetransfer. It's not on req.body or req.query, and when I look through the entire req I can't seem to locate the file. The app flow is working enough to actually make the POST request to test/photos, I just don't know how to or if I can access the file at that point.
How does Filetransfer work, and how can I access the data I need in my controller so that I can push it to Azure Blob Storage?
It looks like you have everything setup correctly to send the data through to your controller. The issue is that you need to put the file on the request since cordova's filetransfer plugin doesn't do that by default.
You can do that with a popular library multer.
npm install multer --save-dev To install multer and save it to your package.json file.
In your express config file, add something like the following:
var multer = require('multer');
app.use(multer({ dest: path.resolve(config.root, 'public/img/') }))
'public/img/' is the path you would like for your image to be saved.
Now your req will have files on it. To upload a single file, you would use req.files.file. You'll want to use this variable to send your file to azure's blob storage using something like blobSvc.createBlockBlobFromLocalFile(containerName, fileName, filePath)
Since you're using Azure for remote storage, chances are you will want to remove the local file that multer has saved. I'd recommend using fs or rimraf to remove the file stored in public/img/, or whatever you set the path to in your express config. If you are using fs, you'll want to use the .unlink command.

Expressjs file download - not downloading

I can't seem to get my "download file" feature working using Expressjs.
//DOWNLOAD FILE
router.get('/snippets/download', function (req, res) {
res.attachment("untitled.js");
res.send("here is some javascript");
});
If I access this route in my browser the file downloads to my computer but not if I use an Angularjs request to the route.
Am I missing something?
You can use res.download. Refer documentation here: http://expressjs.com/4x/api.html
Eg:
//DOWNLOAD FILE
router.post('/snippets/download', function (req, res) {
res.download(req.body.filename, req.body.text);
});
See if this helps.
The res.download() method need a file's full path ( which could be different in windows and linux with different seperator ).
And the 2nd param of res.download(localName, downloadPromptName ) should be able to modify the filename that user see (different from the file in your server's directory), but it seems that does not work in my environment.
So I recommend you to use res.sendFile(fullNameInServer ,options) where you can modify the downloaded filename in options.
var root = getDownloadRoot(req);
var options = {
root: getDownloadRoot(req),
headers: {
"content": "text/html;charset=utf-8",
"Content-Type": "application/octet-stream",
"Expires":"0",
"Cache-Control": "must-revalidate, post-check=0, pre-check=0",
"content-disposition": "attachment;filename=" + urlencode(downloadFilename)
}
};
res.sendFile( tempFileName ,options);
urlencode should be required to encode filename then you can use filename other than english.
before call download file , you need to write the file physically in a temp folder,
the getDownloadRoot() method give you the temp folder location in runtime which does not vary when you change the path to run the app.
here is the function getDownloadRoot()
function getDownloadRoot(req){
var path = require('path');
var sep = path.sep;
var parentPath = path.dirname(req.settings.views);
var ret = parentPath.concat(sep + tempFileFolder);
return ret;
}
For now I have no way other than using app.setting (that app is declared in app.js) to get the application folder during runtime. So I made a litte 'middleware' to transport the value with req object as following.
In app.js:
app.use(function(req, res, next) {
req.settings = app.settings;
next();
});
tempFileFolder is a folder that you can name it yourself.
sep is the folder seperator ( \ in windows and / in linux )
Also you need to watch the folder permission settings when running in linux.
This combination works perfectly in my environment (with angularjs)

How to create project in node.js using html5 and mysql?

I want to include my another js file and one html file(dashboard.html).How it will possible?
var file = require('display.js'),
var http = require('http'),
fs = require('fs');
fs.readFile('./dashboard.html',file, function (err, html) {
if (err) {
throw err;
}
http.createServer(function(request, response) {
response.writeHeader(200, {"Content-Type": "text/html"});
response.write(html);
response.end();
}).listen(9236);
});
Please suggest me proper way to do this thing?
In nodejs if you want to add your own libraries/js.
use this
var file = require('./display.js'), // or the path to file it will load file from path
instead of
var file = require('display.js'), // here it will search in node_modules filder
You should know how node look for modules. I'm adding what I know.
If you will require some ./somefolder/somefile.js it will search for the path ./somefolder/somefile.js and load that file.
If you will add 'somefile.js it will search for the librery somefile.js to node_modules folder in your root directory. If it won't get the file there it will go to global path of node_modules.
If it didn't get that file in global node_modules also, it throws an error
Cannot find module <file.js>
Anyone can improve my answer if anything I missed.

Resources