5

For whatever reason the callback for fs.promises is not being called, yet the documentation makes no mention of it only being called if there's an error, which is what I'm assuming would happen...

fsp.writeFile('test.txt', 'callback doesnt work', 'utf8', (error) => {
  console.log('callback is never called')
  if (error) console.error(error)
})

This is happening (or not happening lol) on version 12.13.0 of Node.

Does anybody know what the deal with this is?

oldboy
  • 5,729
  • 6
  • 38
  • 86

1 Answers1

6

The fs.promises version of async calls return promises. They don't accept callbacks. Use the regular fs version if you want to use a callback.

You can see right here in the doc that there is no option to pass a callback for the fsPromises versions of the API.

You should be doing it like this:

const fsp = require('fs').promises;

fsp.writeFile('test.txt', 'promise works', 'utf8').then(() => {
    console.log("write successful");
}).catch(err => {
    console.error(err);
});

Or, inside an async function, you could use try/catch and await instead of .then() and .catch().

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • oh yeah makes sense, but then why does the [documentation](https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback) say theres a callback?? lol – oldboy Oct 28 '19 at 02:21
  • oh yeah sorry im trippin out. node is new to me if you couldnt already tell lol – oldboy Oct 28 '19 at 02:22
  • @PrimitiveNom - You're looking at the `fs.writeFile()` portion of the doc, not the `fs.promises.writeFile()` [portion of the doc](https://nodejs.org/api/fs.html#fs_fspromises_writefile_file_data_options). – jfriend00 Oct 28 '19 at 02:23
  • yeah i noticed that after looking at the link in your edit. anyways, so would the following syntax suffice for handling the promise? `fsp.writeFile('test.txt', 'testing', error => error)` or should i be handling the promise in a different way? promises are new to me too :/ – oldboy Oct 28 '19 at 02:25
  • @PrimitiveNom - I'd suggest some reading and studying about promises. See what I added to the end of my answer for the proper syntax for the promises version of that API. – jfriend00 Oct 28 '19 at 02:30
  • i have read quite a bit about promises, and i understand the basic stuff like `new Promise(res, rej => { if (cond) {resolveFn(dataPassedForward)} else {rejectFn(dataPassedForward)}).then(data => {do whatever}).catch(data=>{throw data})` but when using them with `fs.promises` its super confusing for me. i always end up in callback hell when everything is working as expected lol. do u know any good reading materials regarding escaping callback hell with `fs.promises`? – oldboy Oct 28 '19 at 02:38
  • like super nested `fs.promises` – oldboy Oct 28 '19 at 02:44
  • @PrimitiveNom - Well, you should chain rater than nest. Promise logic does not usually need to get deeply nested. Or, you can use `await` which allows you to write very flat-looking code. I can't really turn this answer into a promises tutorial. I don't have any particular reading references to recommend. If you read every question/answer here going forward that is tagged `Promise` (or even read the last few months), you'd be surprised what you learn from seeing all those promise-based problems get solved. – jfriend00 Oct 28 '19 at 03:04
  • The `fsPromises` APIs just return a promise that you then use `.then()` and `.catch()` directly on their return value. Just like in the example I show in my answer. – jfriend00 Oct 28 '19 at 03:05
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/201481/discussion-between-primitivenom-and-jfriend00). – oldboy Oct 28 '19 at 03:51
  • @PrimitiveNom - Some other answers to read: [How to handle nested promises](https://stackoverflow.com/questions/48695770/is-there-a-better-way-to-handle-nested-promises-in-nodejs/48696006#48696006), [How to chain and share prior results](https://stackoverflow.com/questions/28714298/how-to-chain-and-share-prior-results-with-promises/28714863#28714863). – jfriend00 Oct 28 '19 at 04:22
  • ty sir. i think i just realized how to do it. i can simply return the value that i need from each `then` function to use in the next `then` function :) – oldboy Oct 28 '19 at 04:23
  • @PrimitiveNom - Yes, you can return a value or another promise. That's how you "chain" with promises. – jfriend00 Oct 28 '19 at 04:24
  • it was tricky to figure out because i had to store some of the values in a higher scope to preserve them. thats y it was hard for me to understand how to chain them – oldboy Oct 28 '19 at 21:28
  • 1
    @PrimitiveNom - Did you see this [How to chain and share prior results with promises](https://stackoverflow.com/questions/28714298/how-to-chain-and-share-prior-results-with-promises/28714863#28714863)? Note how much simpler it is with `async/await`. – jfriend00 Oct 28 '19 at 22:06
  • i did see it, but i never read the inline comments, so i didnt think i would be able to use it in my situation. i guess i can and now i will :D im gonna do some more reading on `async/await` right now before i implement that tho. thanks again for all ur help. really appreciate it – oldboy Oct 29 '19 at 04:54
  • actually im no longer sure anymore that `async/await` is the right approach for what im trying to do. it may just be ignorant and have to read more to get a better understanding of how to accomplish what it is i want to do – oldboy Oct 29 '19 at 05:27
  • @PrimitiveNom - Since all you've shown so far is a single fs asynchronous call, there's not much we do to help. If you want further help, I'd suggest you post a new question and include the code for a much larger context for what you're trying to do and folks will have a better chance to advise what your options are both with and without `async/await`. – jfriend00 Oct 29 '19 at 05:31
  • im just about to head off for the night, but i will do that tomo if need be. one quick question, is `const r = await () => somePromiseOrValue()` not valid syntax? it throws the error `Malformed arrow function parameter list`. anyways gnite – oldboy Oct 29 '19 at 05:43
  • @PrimitiveNom - You `await` a value (that should be a promise), you don't await a function. You can await the result of a function call as in `const r = await someFunc()`. And, apparently you're not even correctly defining the arrow function. That looks wrong to me, but you don't show even a whole statement of code to really see the intent. – jfriend00 Oct 29 '19 at 05:46
  • you mind taking a look at [this question here](https://stackoverflow.com/q/58619990/7543162) – oldboy Oct 30 '19 at 07:26