cannot pass learnyounode: is the callback function used uncorrectly? - node.js

I am trying to solve the sixth problem of learnyounode which needs a module file to print file list. Here are my two files:
The main file program.js:
var mymodule = require('./module.js');
mymodule(process.argv[2], process.argv[3], function(err, file){
if(err){
console.log(err);
return;
}
console.log(file);
});
The module file module.js:
var fs = require('fs');
var path = require('path');
var fileExt;
module.exports = function(dir, ext, callback) {
fs.readdir(dir, function(err, files){
if(err){
callback(err);
return;
}
files.forEach(function(file){
fileExt = path.extname(file).substring(1);
if(fileExt === ext){
callback(null, file);
}
});
});
}
But it throws an error:
processors[i].call(self, mode, function (err, pass) {
TypeError: Cannot read property 'call' of undefined
What am I doing wrong?

The instructions state that you need to call callback only once, with an array containing of all the matching files. In your case, you are calling callback once for every matching file.

Related

Node.js script to copy files overwriting previous ones?

I wish to create a Node.js script to copy files overwriting previous versions of the same files.
My code doesn't work:
const fs = require('fs');
var src = "srcPath/file.json";
var newPath = "newPath/file.json";
var callback = (result) => {
console.log(result);
}
copy(src, newPath, callback);
function copy(src, newPath, callback){
fs.copyFile(src, newPath, (err) => {
if (err) {
callback("Error Found:", err);
}
else {
callback("Success: "+newPath);
}
});
}
execute()
It will work, if you take this line off:
execute()

fs.stat never finds file

I'm trying to create a function in node that will generate an article page if it can find the requested article's json, but I can't even get fs.stat to tell me that a file exists. I've verified the directory and the filename of the script with the __dirname and __filename globals, but I can't even get my function to find a file that's in the same directory as the script, much less a different directory.
var express = require('express');
var fs = require('fs');
var router = express.Router();
var articlePage = function home(req, res) {
console.log(__dirname + __filename);
fs.stat('foo.txt', function(err, stat) {
if(err == null) {
console.log('File exists');
res.send("filefound"); //this never is triggered
} else if(err.code == 'ENOENT') {
console.log("file does not exist");
res.status(404).send('file not found');
} else {
console.log('Some error has occured');
}
});
};
router.get('/article/:articleName', articlePage);
module.exports = router;

Reading a .txt file with NodeJS using FS

I'm trying to use NodeJS to read a txt file by using fs. This is the code of app.js:
var fs = require('fs');
function read(file) {
return fs.readFile(file, 'utf8', function(err, data) {
if (err) {
console.log(err);
}
return data;
});
}
var output = read('file.txt');
console.log(output);
When i do:
node app.js
It says
undefined
I have fs installed and there is a file.txt in the same directory, why is it not working?
Your read function is returning the result of the fs.readFile function, which is undefined because it doesn't have a return clause (it uses callbacks). Your second return clause is in an anonymous function, so it only returns to that scope. Anyhow, your function knows its finished after that first return.
The standard way to use fs.readFile is to use callbacks.
var fs = require('fs');
function read(file, callback) {
fs.readFile(file, 'utf8', function(err, data) {
if (err) {
console.log(err);
}
callback(data);
});
}
var output = read('file.txt', function(data) {
console.log(data);
});

Move File in ExpressJS/NodeJS

I'm trying to move uploaded file from /tmp to home directory using NodeJS/ExpressJS:
fs.rename('/tmp/xxxxx', '/home/user/xxxxx', function(err){
if (err) res.json(err);
console.log('done renaming');
});
But it didn't work and no error encountered. But when new path is also in /tmp, that will work.
Im using Ubuntu, home is in different partition. Any fix?
Thanks
Yes, fs.rename does not move file between two different disks/partitions. This is the correct behaviour. fs.rename provides identical functionality to rename(2) in linux.
Read the related issue posted here.
To get what you want, you would have to do something like this:
var source = fs.createReadStream('/path/to/source');
var dest = fs.createWriteStream('/path/to/dest');
source.pipe(dest);
source.on('end', function() { /* copied */ });
source.on('error', function(err) { /* error */ });
Another way is to use fs.writeFile. fs.unlink in callback will remove the temp file from tmp directory.
var oldPath = req.files.file.path;
var newPath = ...;
fs.readFile(oldPath , function(err, data) {
fs.writeFile(newPath, data, function(err) {
fs.unlink(oldPath, function(){
if(err) throw err;
res.send("File uploaded to: " + newPath);
});
});
});
Updated ES6 solution ready to use with promises and async/await:
function moveFile(from, to) {
const source = fs.createReadStream(from);
const dest = fs.createWriteStream(to);
return new Promise((resolve, reject) => {
source.on('end', resolve);
source.on('error', reject);
source.pipe(dest);
});
}
This example taken from: Node.js in Action
A move() function that renames, if possible, or falls back to copying
var fs = require('fs');
module.exports = function move (oldPath, newPath, callback) {
fs.rename(oldPath, newPath, function (err) {
if (err) {
if (err.code === 'EXDEV') {
copy();
} else {
callback(err);
}
return;
}
callback();
});
function copy () {
var readStream = fs.createReadStream(oldPath);
var writeStream = fs.createWriteStream(newPath);
readStream.on('error', callback);
writeStream.on('error', callback);
readStream.on('close', function () {
fs.unlink(oldPath, callback);
});
readStream.pipe(writeStream);
}
}

Why is this readFile operation in Node throwing an error?

I have this code using socket.io on a Node server:
io.sockets.on(
'connection'
,function (socket) {
reader = require('fs');
fileContents = reader.readFile(__dirname + '/textCharacters.txt'
,'utf8'
,function(data, err) {
if (err) throw err;
console.log(data);
}
);
socket.emit('retrievedFileContent', {content:fileContents} );
}
);
When I check the Node server debug, the error shows the contents of the file, so I know the file is being read, but why isn't it being returned to the fileContents variable?
Because the readFile(filename, encoding, callback) function doesn't return the file contents, it passes them as the second argument to the given callback function. Try modifying your code as such:
var fs = require('fs');
io.sockets.on('connection', function (socket) {
var filename = __dirname + '/textCharacters.txt';
fs.readFile(filename, 'utf8', function(err, data) {
if (err) throw err;
socket.emit('retrievedFileContent', {content:data});
});
});

Resources