0

I've separate some logic to different file in my project, the problem is that I got the following error

Cannot read property 'readFile' of undefined

this is the structure of my project

projName
   utils
     file.js

the file.js code is

module.exports = function () {
   var  fs = require('fs');
    function readFile(filePath) {
        fs.readFile(filePath, 'utf8', function (err, data) {
            if (err) {
                return console.log("error to read file:  " + filePath + " " + err);
            }
            return data;
        });
    }
};

I want to call to this module at

projname
    controller
         request

I do it with the following code And here I got the error

   module.exports = function (app) {
        app.get('/test', function(req, res) {

            var file = require('../utils/file')();
            var fileContent = file.readFile("C://test.txt");

any idea what am I doing wrong here? This is not related to async call

2
  • possible duplicate of How to return the response from an asynchronous call? Commented Jun 9, 2015 at 14:22
  • @Scimonster- this is not related to async ....if you think so please explain since I already read this in the past... Commented Jun 9, 2015 at 14:23

2 Answers 2

2

Your file.js could be like this:

var fs = require('fs');

module.exports.readFile = function (filePath, cb) {
  fs.readFile(filePath, 'utf8', cb);
};

and your request.js file like this:

var file = require('../utils/file');

module.exports = function (app) {

  var fileContent = '';
  var filePath = 'C://test.txt';

  file.readFile(filePath, function (err, data) {
    if (err) {
        return console.log("error to read file:  " + filePath + " " + err);
    }

    console.log(data);
    fileContent = data;
  }); 

  // some content

}

Regarding the async call when you call a method from Node.JS libaries, it is usually a async call, that means that the result of the function is not going to return immediately:

var data = fs.readFile(filePath);

instead it is going to return at some time later, so the only way you can get the results later is passing by a function that is going to be called when the results are ready:

fd.readFile(filePath, function dataReady (err, data) {
  console.log(data)
});

Regarding module.exports when you export some logic of a file that you created in Node.JS, you can return your function on the following ways:

// exporting a function, myModule.js
module.exports = function () { 
  console.log('hello');
};

// consuming myModule.js
var someFunction = require('./myModule.js');
someFunction(); // prints 'hello';

// exporting a function, myModule.js
module.exports.readFile = function () {
  console.log('hello');
};

// consuming myModule.js
var myModule = require('./myModule.js');
myModule.readFile(); // prints 'hello';

UPDATE: In your file.js you are exporting a function that is going to receive a file path and a function called callback as the second parameter (yes, you read it well, a function as a parameter) which is going to be called once the fs.readFile get the file content.

module.exports.readFile = function (filePath, callback) {
  fs.readFile(filePath, 'ut8', function (err, fileContent) {
    callback(err, fileContent);
  });
}

then in your request.js file, you are using your module (file.js) you just created, and the function that your module is exporting accepts a string as parameter called filePath, and a function as parameter called callback: file.readFile(filePath, callback)

so when your module file.js get the content file is going to call to your callback function parameter.

var file = require('../utils/file');

file.readFile(filePath, function (err, data) {
  if (err) {
    return console.log("error to read file:  " + filePath + " " + err);
  }

  console.log(data);
  fileContent = data;
});

I hope that this helps to clarify a little bit your knowledge about callbacks.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks,Im little bit confused regard the callback,can you please provide example how should I use it in my case?
1

You don't return anything in your module.exports function. In fact, you don't even need to set module.exports to a function. Just simply export your function:

var  fs = require('fs');
function readFile(filePath) {
    fs.readFile(filePath, 'utf8', function (err, data) {
        if (err) {
            return console.log("error to read file:  " + filePath + " " + err);
        }
        return data;
    });
}
exports.readFile = readFile;

Also, your return data isn't going to work, as fs.readFile is asynchronous. You need to use callbacks. So, your readFile function might look more like:

function readFile(filePath, callback) {
    fs.readFile(filePath, 'utf8', function (err, data) {
        if (err) {
            return console.log("error to read file:  " + filePath + " " + err);
        }
        callback(data);
    });
}

5 Comments

Thanks voted up!, Can you please show me what to you mean by using callback and if for example I've more then one function to exports how should I do that (e.g. also write file,deleteFile etc) ?
Edited to explain a bit about the callback. And for other functions just do function writeFile(){} exports.writeFile = writeFile; the same way.
Thanks,I try what you write and I got error undefined is not a function in callback(data); any idea?
You also need to pass a callback function when you call file.readFile, like you do in fs.readFile. You might want to review How to return the response from an asynchronous call?.
Thanks but I not sure in my case what shuould I put in the callback...can you provide example....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.