Where should the callback be in fs.writefile? - node.js

I am a beginner to node.js and I have been following an online course when I received this error: TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
fs.writeFile(fileDescriptor, function (err) {
if (!err) {
fs.close(fileDescriptor, function (err) {
if (!err) {
callback('false');
} else {
callback('Error closing existing file');
}
});
} else {
callback('Error writing to existing file');
}
});
I am pretty sure that I have already included a callback here. How should I solve this?

You are not providing a callback function to fs.writeFile (should be the third argument) and the second argument for fs.writeFile should be the data which you want to write.
const fs = require('fs');
const data = "Text, text and more text.";
function callback(err) {
if (err)
console.log(err);
else {
console.log("File written successfully\n");
}
}
fs.writeFile("file.txt", data, callback);
More info:
callbacks: https://codeburst.io/javascript-what-the-heck-is-a-callback-aba4da2deced
fs.writeFile: https://nodejs.org/dist/latest-v16.x/docs/api/fs.html#fswritefilefile-data-options-callback

Related

How do you use got node module with node createWriteStream to download an image with electron?

I have looked at a couple of other answers, but they did not help me.
node version 16.8.0
windows 10
"got": "11.8.2",
electron 14.0.0
Here is what I am trying. The code below does download the file but createWriteStream throws error --
Uncaught (in promise) TypeError [ERR_INVALID_RETURN_VALUE]: Expected
AsyncIterable or Promise to be returned from the "destination"
function but got type undefined.
Code in my render file
module.exports.getTile = async function (url, outputFilePath) {
const pipeline = promisify(stream.pipeline);
await pipeline(
got.stream(url),
fs.createWriteStream(outputFilePath),
(err) => {
if (err) {
console.error('Pipeline failed', err);
} else {
console.log('Pipeline succeeded');
}
});
stream.finished(input, (err) => {
if (err) {
console.error('Stream failed', err);
} else {
console.log('Stream is done reading');
}
});
};
I call the function with await getTile(url, tilePath);
stream.pipeline(...streams, callback) accepts n stream middlewares and a final callback argument as per documentation.
util.promisify(...args, callback) accepts a function with an error-first callback and wraps it into an async function that throw on errors. (docs)
When the two are combined, util.promisify will consume the final callback argument in stream.pipeline, and return an async function that only accept stream middlewares: util.promisify(stream.pipeline)(...streams).
Consequently, the following snippet
await pipeline(
got.stream(url),
fs.createWriteStream(outputFilePath),
(err) => {
if (err) {
console.error('Pipeline failed', err);
} else {
console.log('Pipeline succeeded');
}
});
Should be rewritten as:
try {
await pipeline(
got.stream(url),
fs.createWriteStream(outputFilePath)
)
console.log('Pipeline succeeded');
}
catch( error ){
console.error('Pipeline failed', err);
}

nodejs arrow function not returning expected value

I'm using the aws-sdk to upload a message to kinesis. It works fine but i'm trying to solve for when the action does not work (due to internet being down or something).
Here is the code i'm running.
const returnValue = kinesis.putRecord(params, (err, data) => {
if (err) {
logger.info(err);
return err;
} else {
logger.info(data);
return data;
}
});
console.log(returnValue);
I expect to get back the err or data. Instead what I get back is a Huge json of what I assume is the kinesis.PutRecord request itself.
Any ideas on why i'm not getting data returned to my returValue variable?
The console logs data and error just fine.
UPDATE:
as pointed out in the comments, I needed to wrap the function in a promise. I also put it in a try catch since if you throw a "reject" without a catch you get an unhandled promise rejection.
Updated code here:
try {
const returnValue = await new Promise(function(resolve, reject){
kinesis.putRecord(params, (err, data) => {
if (err) {
logger.info(err);
reject(err);
} else {
logger.info(data);
resolve(data);
}
});
});
logger.log(returnValue);
} catch (error) {
logger.error(error);
return error;
}

I get an error in fileSystem module while using writeFile Asynchronously

I'm trying to use writeFile() inside call back function of readFile() from fileSystem module..
I'm a beginner in node.js I have been watching Youtube tutorials
const fs = require('fs');
fs.readFile('readMe.txt','utf8', function(err, data){
fs.writeFile('writeMe.txt', data);
});
console.log('Fire..');
I get an error pasted below.. I don't understand the type of this error.. can someone help me with this?
Fire..!
fs.js:128
throw new ERR_INVALID_CALLBACK();
^
TypeError [ERR_INVALID_CALLBACK]: Callback must be a function
at maybeCallback (fs.js:128:9)
at Object.writeFile (fs.js:1163:14)
at C:\Users\shahzaib laptops\Desktop\NodeJS\pathModule\fileSystem.js:6:6
at FSReqWrap.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:53:3)
You can use the Following snippet to read and write file what need. You this in common and use this if u need in many place. u need to pass the filename to read and write to this method.
Else directly use the callback alone the parameter in method and jsut give the file name static as u have above.
public ReadandWriteFile(fileNameToRead, fileNameToWrite, callback) {
fs.readFile(fileNameToRead, "utf-8", (err, data) => {
if (err) { console.log(err) }
if (data) {
fs.writeFile(fileNameToWrite, data, (err) => {
if (err) { console.log(err) };
if (data) {
callback({ message: 'Successfully Written to File.' })
}
});
}
})
}
Add proper err handling and callback Fn. in writefile
const fs = require('fs');
fs.readFile('readMe.txt','utf8', function(err, data){
if(err) callback or return err
else{
fs.writeFile('writeMe.txt', data,'utf8', function(err2, data2){
if(err2) callback or return err2
else console.log(data2)
});
}
});
console.log('Fire..');
You can use promise for readFile and writeFile.
const fsPromises = require("fs").promises;
async function readAndWrite() {
let filehandle;
try {
filehandle = await fsPromises.readFile("readMe.txt");
console.log(filehandle);
let writeComleted = await fsPromises.writeFile("writeMe.txt", filehandle);
} catch {
throw new Error("something bad happened");
}
}
readAndWrite();

Node Js call back / promise/ return

I am kind of new to this node js and went through many explanations, tried many solutions but still cant get my head wrapped around the function call backs.
//app.js file
var dashboardfunc = require('./models/admindashboard');
app.get("/dashboard/:id?", function(req, res) {
console.log("we are here in dashboard")
var data = {id: req.params.id};
console.log(data)
dashboardfunc.productlist().then(function(results){
console.log("i am here now ....")
console.log(results)
}).catch(function(err){
if(err){
console.log(err)
}
})
});
//admindashboard.js file
//I tried many other alterations like using call back etc.
// i want the damn results to be back to the app.js and use that
//
function productlist(data) {
return new Promise(function(resolve, reject) {
var param = [data.id];
var sql = 'select * from product where seller_id=?';
console.log(param)
pool.query(sql, param, function(err, results) {
if (err) {
console.log(err)
}
else {
if (results === undefined) {
reject(new Error("Error rows is undefined"));
}
else {
console.log("we got here in productlist")
console.log(results)
return results;
}
}
})
})
}
module.exports = productlist;
<--Result -->
Rb-v2 started !!!
we are here in dashboard
{ id: '23' }
TypeError: dashboardfunc.productlist is not a function
Question is why it is so hard to get the results back , and why it needs to be so complicated to call a function , get the return data. Along with that whats the deal with callback v/s promise ( yeah I read almost all post in it still my naive brain cant process it)
Try these small fixes for the start:
admindashboard.js exports the only function, but app.js tries to use it as a property of an object. You need either this type of export:
module.exports = { productlist };
or this using:
dashboardfunc().then
The argument in the imported function call is missing. Try dashboardfunc(data).then instead of mentioned dashboardfunc.productlist().then.
resolve callback is not used in productlist() function. Use it to return the data from the promise: resolve(results); instead of return results;.
Be consistent in error handling. Use:
if (err) {
reject(err)
}
else {
if (results === undefined) {
reject(new Error("Error rows is undefined"));
}
instead of:
if (err) {
console.log(err)
}
else {
if (results === undefined) {
reject(new Error("Error rows is undefined"));
}

Instructions not executed into the right order with nodejs

I am new to nodejs and trying to cat multiple css files on-the-fly while coding. The package chokidar allow me to call a function when a file is modified, however I have a problem with the execution.
var goconcat =
fs.readdir(paths, function (err, files) {
if (err) {console.log(err);}
fs.unlink(paths + 'concat.css', function (err) {
if (err) throw err;
var list = files.map(function (files) {
return path.join(paths, files);
});
concat(list, paths + 'concat.css', function(err) {
if (err) throw err
});
});
});
I want to first delete the previous file, then read the directory and then write a new "concat.css". However I have an error;
Error: ENOENT: no such file or directory, open 'public/css/concat.css'
at error (native)
It appears that the function concat() is executed before the directory update and not after, and therefore it is trying to cat a file that just have been deleted. Why ?
I know that nodejs is executing functions in a synchronous way but I can't find a way to solve this problem. I tried async but I can't declare a variable between two functions and I couldn't manage to make it work.
If it cannot exist in a callback, using the setTimeout(fn, 0) trick may help make sure it's executed after the variable assignment.
var goconcat =
fs.readdir(paths, function (err, files) {
if (err) {console.log(err);}
fs.unlink(paths + 'concat.css', function (err) {
if (err) throw err;
var list = files.map(function (files) {
return path.join(paths, files);
});
setTimeout(function() {
concat(list, paths + 'concat.css', function(err) {
if (err) throw err
})}, 0);
});
});
The problem you're having is that your concat function is being invoked before the file is deleted by invoking unlink. You can prevent this by having nested callbacks; however, you can probably have better control flow if you use a module like async, and prevent yourself from dealing with Callback Hell.
Below is an example on how you can use the async module.
var fs = require('fs');
var async = require('async');
var myDir = __dirname + '/data';
async.waterfall([function(callback) {
fs.readdir(myDir, 'utf-8', function(error, files) {
if (error) {
return callback(error);
}
return callback(null, files);
});
}, function(files, callback) {
fs.open(myDir + '/myFile', 'wx', function(error, f) {
if (error && error.code === 'EEXIST') {
return callback(null, 'EEXIST');
}
return callback(null, 'CREATE');
});
}, function(fileStatus, callback) {
if (fileStatus === 'EEXIST') {
console.log('File exists. Deleting file...');
fs.unlink(myDir + '/myFile', function(error) {
if (error) {
return callback(error);
} else {
return callback(null);
}
});
} else {
console.log('File does not exist...');
return callback(null);
}
}, function(callback) {
fs.writeFile(myDir + '/myFile', "Hello World", function(err) {
if(err) {
return callback(error);
}
return callback(null, 'File Created');
});
}], function(error, results) {
console.error(error);
console.log(results);
});
The waterfall function runs the tasks array of functions in series,
each passing their results to the next in the array. However, if any
of the tasks pass an error to their own callback, the next function is
not executed, and the main callback is immediately called with the
error.

Resources