Electron dialog.showOpenDialog not running callback - dialog

I have been trying to make a simple program to create and read files with Electron.
So far I have tried a lot and it seems the callback function I provide with the dialog.showOpenDialog is not being called.
dialog.showOpenDialog( (filePaths) => {
console.log('this callback is called');
console.log(filePaths);
});
//Directly read a test file
fs.readFile('readtest.txt', 'utf-8', (err, data) => {
if (err) throw err;
console.log(data);
});
This is the code inside my read button handler.
The dialog opens and I choose a file and it simply does nothing.
However the same file which I selected is read by the fs.readFile and displayed in the console.
It seems the callback is not getting called after I choose the file.

It returns a promise, so you can chain it with .then:
dialog.showOpenDialog(null, options).then((filePaths) => {
console.log('this callback is called');
console.log(filePaths);
});

Related

I keep trying to use require to load in node fs module and it keeps giving me invalid callback error, how do i rectify this

Here is the sourcecode:
console.log('Starting app.');
const fs = require('fs');
fs.appendFile('greetings.txt', 'Hello world!');
fs.appendFileSync('greetings.txt', 'Hello world!');
when i load the app in the terminal, it keeps giving me this error message.
fs.appendFile() is the asynchronous version of that interface and it requires that the last argument be a callback that gives you both completion and/or error conditions.
See the doc.
fs.appendFile(path, data[, options], callback)
The callback is NOT optional.
The proper usage of that function would be this:
fs.appendFile('greetings.txt', 'Hello world!', err => {
if (err) {
console.log(err);
} else {
console.log("data appended successfully");
}
});
Also, please note that this is asynchronous and non-blocking so the callback will get called some indeterminate time later (when the append finishes), but the next lines of code after this will execute immediately (before the callback is called).
Other relevant interfaces are the promise version of the asynchronous interface:
fs.promises.appendFile(path, data[, options])
You do not pass a callback to this version. Instead, it returns a promise which you use to get notified of completion/error.
fs.promises.appendFile('greetings.txt', 'Hello world!').then(() => {
console.log("data appended successfully");
}).catch(err => {
console.log(err);
});
For asynchronous interfaces, the promise-version is newer and considered more modern.

Unit Testing using mocha, node

I'm new to unit testing in the Node world and am struggling with this: I've setup a after cb to delete the records I've added during my tests, however I keep getting an error Error: done() called multiple times every time I delete the record on the db. Here's my code:
after((done) => {
User.deleteOne({email: user_email}, function(err, result) {
if(err) console.log(err);
console.log(result);
done();
});
});
If I do anything else (like just console something within the after block, I get no error at all.
What am I doing wrong?
Try with async/await style.
after(async () => {
const deleteResult = await User.deleteOne({email: user_email});
console.log(deleteResult);
});
With async/await you don't need to execute done, because mocha automatically handle promises.
More here and here

Write the sum of the values in to another file using Nodejs asynchronously

I have a file readData.txt has the values "10,20,30,40,50,........"like this I have the numbers.
Now I want to write the sum of those values in to the other file called sumfile.txt. I'm using fs.readFile and fs.writeFile functions which are asynchronous.
I have tried using Promises, It worked. But I'm curious that can we do it without using Promises. I'm trying to achieve that without Promises.
If anybody know any other ways I'll be thankful.
You can use the callback parameter of fs.readFile:
fs.readFile('/etc/passwd', (err, data) => {
if (err) throw err;
console.log(data);
});
You can use the callback parameter of fs.writeFile:
const data = new Uint8Array(Buffer.from('Hello Node.js'));
fs.writeFile('message.txt', data, (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
EDIT
You can do this synchronously as well, using fs.readFileSync
fs.readFileSync('<directory>');
and fs.writeFileSync
But it is better to keep things async. It is difficult at first, but all your struggles will be rewarded.

Unable to write to file in message handler

I am coding a Discord bot that can write to a local text file on glitch.com.
When I use the ready event handler my program is able to write to the file just fine:
client.on('ready', () => {
fs.appendFile('./log.txt', 'Hello\n', (err) => {
if(err) throw err;
});
});
//Writes to file
However, when I try to write to the same file using the message event handler, nothing happens:
client.on('message', (message) => {
fs.appendFile('./log.txt', 'Hello\n', (err) => {
if(err) throw err;
});
});
//Does not write to file
Do I need to change permissions on this file? Or change it from a local file? Any help would be greatly appreciated.
I think something like this might work, I don't have time to test it but it's using the writeFile() method as opposed to the appendFile() method
client.on('message', (message) => {
fs.writeFile('./log.txt', message, (err) => {
if(err) throw err;
});
});
Assuming you already have your local text file you wouldn't need to make a new one. So you may as well use writeFile(), only thing I can see going wrong with this is it may refresh the file every message, but you could probably fix that with a message collector that updates the file every say 100 messages.
Using appendFileSync instead of appendFile should fix your issue, as appendFileSync is more reliable and has less of a chance to create errors. Good luck!

In node, how do you wait until a callback has been called?

I have a function which resolves by taking a callback like function(error, result) { ... } as a parameter. I'm trying to use mocha to test this function, but the problem is that the function returns asynchronously, so there's no good place for me to put the done(). If I put inside my result handler, it takes too long and mocha times out. If I put it outside, the test always passes because the handler hasn't been called yet. Here is my code. What's the best way to get around this?
lbl.createLabels is a function that takes an array of customers, and a directory, and creates a bunch of files in that directory, and then asynchronously calls the callback of type: function(error, callback).
describe('Tests', () => {
it('returns a list of customer objects', (done) => {
lbl.createLabels(customers, __dirname + "/..", (err, result) => {
err.should.equal(undefined)
result.should.be.a('array')
result[0].should.have.property('id')
result[0].should.have.property('tracking')
result[0].should.have.property('pdfPath')
const a = {prop:3}
a.prop.should.be.an('array')
done() // putting done() here results in a timeout
})
done() // putting done here results in the test exiting before the callback gets called
})
})
Mocha's documentation has an entire section describing how to test asynchronous code:
https://mochajs.org/#asynchronous-code
Testing asynchronous code with Mocha could not be simpler! Simply invoke the callback when your test is complete. By adding a callback (usually named done) to it(), Mocha will know that it should wait for this function to be called to complete the test.
describe('User', function() {
describe('#save()', function() {
it('should save without error', function(done) {
var user = new User('Luna');
user.save(function(err) {
if (err) done(err);
else done();
});
});
});
});

Resources