As people have noted in the comments, the problem with your code is that you are missing the concept of asynchronous execution. If you add a few console.log() statements to your code to see when each step is executed you will be able to spot the problem:
var fs = require('fs');
function sql_file(sql_file, cb) {
console.log('about to read file');
var fileName = "./SQLs/" + sql_file;
fs.readFile(fileName, function(err, buffer) {
console.log('the file has been read');
if (err) return cb(err);
return cb(null, buffer.toString());
});
console.log('call to read file made (but not finished)');
// the call to sql_file ends here and returns nothing/undefined
}
var t = sql_file('inventory.sql', function(err, contents) {
// contents will have the value when this call back is executed
// in your case this is once the file has been read.
// Keep in mind that sql_file will ALWAYS return null, though.
return contents.toString();
});
console.log(t);
If you run your code with these console.log() you'll see why you are always getting undefined. Once your code uses an async call (like fs.readFile) you cannot depend on linear execution of the code.
You should write your code as follow in order for you to print the value as you intended:
var fs = require('fs');
function sql_file(sql_file, cb) {
console.log('about to read file');
var fileName = "./SQLs/" + sql_file;
fs.readFile(fileName, function(err, buffer) {
console.log('the file has been read');
if (err) return cb(err);
return cb(null, buffer.toString());
});
console.log('call to read file made (but not finished)');
}
// sql_file will always return NULL but the value will
// be available to you once the callback is executed.
sql_file('inventory.sql', function(err, contents) {
console.log(contents.toString());
});
The take away here is that once you've gone async you are all in. You cannot expect the value to be available in the next line when one of the calls (fs.readFile in your case) is asynch.