1

I am new to node.js so I am trying to understand promises and wait on node.js. I want to print the file note.txt.

Here is my code

    var fs = require('fs');

    fs.readFile('note.txt','utf8').then(contents => console.log(contents))
    .catch(err => console.error(err));

When I run above code. I get the following error.

fs.readFile('note.txt','utf8').then(contents => console.log(contents))

    TypeError: Cannot read property 'then' of undefined
        at Object.<anonymous> (/Applications/nodeApps/test/index.js:13:31)
        at Module._compile (module.js:635:30)
        at Object.Module._extensions..js (module.js:646:10)
        at Module.load (module.js:554:32)
        at tryModuleLoad (module.js:497:12)
        at Function.Module._load (module.js:489:3)
        at Function.Module.runMain (module.js:676:10)
        at startup (bootstrap_node.js:187:16)
        at bootstrap_node.js:608:3

And I try another method for the same thing.

var fs = require('fs');

async function  read_file(){
  var file_data = await  fs.readFile('note.txt','utf8');
    return file_data;

}
console.log(read_file());

And I get following error

Promise { <pending> }
(node:6532) [DEP0013] DeprecationWarning: Calling an asynchronous function without callback is deprecated.

I get the same error when I run with --harmony. I m not sure if there is bug on my code or what is wrong. Please help me understand.

My Environment Node version: v8.9.0

node -p process.versions.v8: 6.1.534.46

Krishna Karki
  • 749
  • 12
  • 31
  • 2
    `readFile` simply doesn't return a promise (in fact it returns `undefined`, according to the error you are getting). It only accepts a callback. https://nodejs.org/api/fs.html#fs_fs_readfile_path_options_callback . There are however third party modules that wrap native Node APIs in promises. – Felix Kling Jul 15 '18 at 07:06
  • @FelixKling [Not just third party ones](https://nodejs.org/api/util.html#util_util_promisify_original) – Bergi Jul 15 '18 at 08:52
  • Possible duplicate of [NodeJS: Confusion about async "readdir" and "stat"](https://stackoverflow.com/questions/51180577/nodejs-confusion-about-async-readdir-and-stat) – Estus Flask Jul 15 '18 at 11:48
  • @FelixKling [Not at all](https://nodejs.org/api/fs.html#fs_fs_promises_api). – Estus Flask Jul 15 '18 at 11:49
  • @Bergi: ah, didn’t realize they already added it, I thought they were still working on it. Who can keep up these days :P not sure how it feel about experimental APIs though :D – Felix Kling Jul 15 '18 at 12:16
  • @FelixKling Oh right there's also the `fs.promises` API, but `util.promisify` is stable. – Bergi Jul 15 '18 at 13:55
  • @Bergi ah, must have looked at estus’ link (phone). Anyways, I didn’t know about `utils.promisify` either. Thanks! – Felix Kling Jul 15 '18 at 15:09

4 Answers4

1

You're getting errors because fs.readfile doesn't return a promise; hence then doesn't exist. For you to use the function as a promise, you will need to wrap it up as a promise; you could use something like bluebird or Q.

MrPooh
  • 59
  • 1
  • 5
  • is there a method to check if function returns a promise or not? – Krishna Karki Jul 15 '18 at 07:59
  • @KrishnaKarki The most reliable method is to read the documentation. This is one reason why javascript libraries are often very well documented (often with very fancy websites) compared to languages like Java where you can discover this from the syntax itself (hence your IDE can suggest intellisense) where library documentation are usually just what Javadoc generates – slebetman Jul 15 '18 at 10:35
1

Thank you for the answers. I learned that function must return promise in order to use then() and catch(). So the code should be like this

var fs = require('fs');

  function  read_file(){
    return new Promise(function(resolve, reject) {
         fs.readFile('note.txt','utf8',function(err,file){
            if(err){
                return reject(err);
            }else{
                resolve(file);
            }
        });
    });


}

read_file().then(
    (data)=>{
        console.log('success: '+data);
    }
).catch((err)=>{
    console.log('error: ',err);
});
Krishna Karki
  • 749
  • 12
  • 31
1

If you use NodeJs v10, try fs.promises:

var fs = require('fs').promises; // v10.0 use require('fs/promises')

fs.readFile('note.txt','utf8').then(contents => console.log(contents))
.catch(err => console.error(err));

If not, use readFileSync:

// This code can use for node v10 or lowwer
var fs = require('fs');

var data = fs.readFileSync('a.json');
console.log(data);
hong4rc
  • 3,999
  • 4
  • 21
  • 40
0

try to use the async await

function (async  err => {
    if (err) {
       console.err ....}

    await .... <other function included or comes after then .>
    await ... <other function included>
})