How can I read a pdf file with express and node - node.js

I'm trying to read a pdf... and my idea is to convert it to a text. I have read the pdf-parser documentation and I don't understand why it is giving me this error, has anyone ever used pdf-parser?
Has anyone had this error?
It would be very helpful, I have never worked with it and the videos I watched use it very easily, but it breaks the code for me.
const url = require("./prueba.pdf");
const pdf = require("pdf-parse");
const fs = require("fs");
const pdffile = fs.readFileSync(url);
console.log(pdffile);
pdf(pdffile).then(function (data) {
console.log(data.text);
});

The path ./prueba.pdf is not correct, unless you run the node command from the ..\api\src\routes subdirectory, which I doubt.
Unlike paths in a require command, paths in an fs.readFileSync command are interpreted relative to the directory where you started the node process.

Related

rootDirName returning wrong part of the path

I have a Gulpfile which runs in the 'theme' folder of my project.
C:\wamp\www\mywebsitename\wp-content\themes\mythemename\gulpfile.js
In the gulpfiule, need to get the local website URL, which is basically just the 'mywebsitename' part of this path.
I have historically used this code to get it successfully:
"var rootDirName = path.basename(__dirname, '../../../');"
However I recently re-installed Windows, Node and Gulp, and now that line of code returns 'mythemename' instead of 'mywebsitename', ignoring the '../../../' argument.
If I remove that argument, it stil returns 'mythemename'.
I'm guessing some newer version of Gulp, Node or something in Windows has changed how this method works. Please can anyone suggest why this no longer works, or if there is a better way to always go 3 levels up the file tree from the gulpfile.js directory?
Worked it out myself.
const path = require('path');
var rootDirPath = path.join(__dirname, '../../../');
var rootDirName = path.basename(rootDirPath);
var url = 'http://localhost/' + rootDirName;
This will allow you to get the website's URL on localhost in Gulp and do what you need to with it (in my case, using the Critical CSS tool to scan the website and inline all the header CSS).

Working when run, but not when built

Im on macOS. I am creating a simple electron app. When I run the app with electron . everything works perfectly with no errors. Now that my app is finished, I wanted to build and distribute it. So I setup electron-builder and I got that to work just fine. However, when I run the MyApp.app in the build folder, I get an error saying:
Uncaught Error: ENOENT: no such file or directory, scandir './img/'
I call scandir here:
const fs = require('fs');
var files = [];
fs.readdirSync("./img/").forEach(file => {
files.push(file);
})
Why is this working when I run it with node, but is not working in the build? How can I fix this issue?
Why is this working when I run it with node, but is not working in the
build? How can I fix this issue?
It's difficult to tell without having more information about the whole app's structure, it may depend on how your code is actually called or required from the html file.
Anyway, using the __dirname global variable to build the directory path usually solves this kind of problem. Please try:
const fs = require('fs');
const path = require('path');
var files = [];
fs.readdirSync(path.join(__dirname, 'img')).forEach(file => {
files.push(file);
});

nodeJS:fs.write callback and fs.writeFile not working

I knew nothing about fs until I was learning to use casperjs to scrape some content from a website and save them to a file. Following some examples on the web, I write this file scrape.js (The json data has been tested so it has nothing to do with the issue):
var fs = require('fs');
var url = "http://w.nycweb.io/index.php?option=com_k2&view=itemlist&id=4&Itemid=209&format=json";
var casper = require('casper').create();
casper.start(url,function(){
var json = JSON.parse(this.fetchText('pre'));
var jsonOfItems={},items = json.items;
items.forEach(function(item){
jsonOfItems[item.id] = item.introtext.split('\n');
})
fs.write('videoLinks.json',JSON.stringify(jsonOfItems),function(err){
if (err) console.log(err);
console.log('videoLinks.json saved');
})
});
casper.run();
When I do casperjs scrape.js in command line of my Ubuntu 14.04 server, I won't see the file saved message as expected, although the file is properly saved. So this is the first question: why the callback isn't running at all?
Secondly, I also tried fs.writeFile, but when I replace fs.write with it, the file isn't saved at all, nor is there any error information.
I do notice that in casper documentation it's said that casper is not a node.js module and some module of node.js won't be available, but I doubt it has anything to do with my issues. And I think it worths to mention that previously when I run this script I only get a respond like
I'm 'fs' module.
I had to follow this question to reinstall fs module globally to get it working.
fs.write expects a file descriptor where you are trying to give it a filename. Try fs.writeFile. https://nodejs.org/dist/latest-v4.x/docs/api/fs.html#fs_fs_writefile_file_data_options_callback
Edit: Oh you tried that. Are you sure it didn't write it somewhere like the root directory? Tried a full path in there?
And what version of node are you running?

Get application full path in Node.js

I'm wondering if there is a best way or best practice to get the full path of application in Node.js. Example: I have a a module in sub folder /apps/myapp/data/models/mymodel.js, and I would like to get the full path of the app (not full path of the file), which will return me /apps/myapp, how do I do that? I know _dirname or _file is only relative to the file itself but not the full path of the app.
There's probably a better solution, BUT this should work:
var path = require('path');
// find the first module to be loaded
var topModule = module;
while(topModule.parent)
topModule = topModule.parent;
var appDir = path.dirname(topModule.filename);
console.log(appDir);
EDIT: Andreas proposed a better solution in the comments:
path.dirname(require.main.filename)
EDIT: another solution by Nam Nguyen
path.dirname(process.mainModule.filename)
This worked for me.. With supervisor running the app from a different dir.
require('path').dirname(Object.keys(require.cache)[0])
example.. files:
/desktop/ya/node.js
require('./ya2/submodule')();
/desktop/ya/ya2/submodule.js
module.exports = function(){
console.log(require('path').dirname(Object.keys(require.cache)[0]))
}
$ node node.js
=> /desktop/ya
$ (from /desktop) supervisor ya/node.js
=> /desktop/ya

Proper way to reference files relative to application root in Node.JS

I have a Node.JS application running on Linux at AWS EC2 that uses the fs module to read in HTML template files. Here is the current structure of the application:
/server.js
/templates/my-template.html
/services/template-reading-service.js
The HTML templates will always be in that location, however, the template-reading-service may move around to different locations (deeper subdirectories, etc.) From within the template-reading-service I use fs.readFileSync() to load the file, like so:
var templateContent = fs.readFileSync('./templates/my-template.html', 'utf8');
This throws the following error:
Error: ENOENT, no such file or directory './templates/my-template.html'
I'm assuming that is because the path './' is resolving to the '/services/' directory and not the application root. I've also tried changing the path to '../templates/my-template.html' and that worked, but it seems brittle because I imagine that is just resolving relative to 'up one directory'. If I move the template-reading-service to a deeper subdirectory, that path will break.
So, what is the proper way to reference files relative to the root of the application?
Try
var templateContent = fs.readFileSync(path.join(__dirname, '../templates') + '/my-template.html', 'utf8');
To get an absolute filesystem path to the directory where the node process is running, you can use process.cwd(). So assuming you are running /server.js as a process which implements /services/template-reading-service.js as a module, then you can do the following from /service/template-reading-service.js:
var appRoot = process.cwd(),
templateContent = fs.readFileSync(appRoot + '/templates/my-template.html', 'utf8');
If that doesn't work then you may be running /service/template-reading-service.js as a separate process, in which case you will need to have whatever launches that process pass it the path you want to treat as the primary application root. For example, if /server.js launches /service/template-reading-service.js as a separate process then /server.js should pass it its own process.cwd().
Accepted answer is wrong. Hardcoding path.join(__dirname, '../templates') will do exactly what is not wanted, making the service-XXX.js file break the main app if it moves to a sub location (as the given example services/template).
Using process.cwd() will return the root path for the file that initiated the running process (so, as example a /Myuser/myproject/server.js returns /Myuser/myproject/).
This is a duplicate of question Determine project root from a running node.js application.
On that question, the __dirname answer got the proper whipping it deserves.
Beware of the green mark, passers-by.
For ES modules, __dirname is not available, so read this answer and use:
import { resolve, dirname, join } from 'path'
import { fileURLToPath } from 'url'
import fs from 'fs'
const relativePath = a => join(dirname(fileURLToPath(import.meta.url)), a)
const content1 = fs.readFileSync(relativePath('./file.xyz'), 'utf8') // same dir
const content2 = fs.readFileSync(relativePath('../file.xyz'), 'utf8') // parent dir
We can use path madule to access the current path
const dirname = __dirname;
const path = require('path');
path.resolve(dirname, 'file.txt')
where
dirname - is give us present working directory path name
file.txt - file name required to access

Resources