Reputation: 929
I'm a Node.js newbie trying to send back data to the browser by accessing a function load_blocks()
in an external file I wrote and call it with res.send()
.
I have two simple files:
The first one is the typical app.js
file:
const express = require('express');
const app = express();
//import my file
const blockchain = require('./load_blockchain.js');
app.get('/', function(req, res){
res.send('<h3>' + blockchain.load_blocks() + '</h3>');
});
app.listen(3000, function(){
console.log('Example app listening on port 3000!');
});
load_blockchain.js
This file has a function load_blocks() which is meant to read the lines of a file and then return them as text. But when I load my page, the <h3>
tag reads undefined
var fs = require('fs');
var readline = require('readline');
module.exports = {
load_blocks: function (){
//Load The File
var return_string = "";
var rd = readline.createInterface({
input:fs.createReadStream('/home/blockchain_data/1.dat$
output: process.stdout,
console: true
});
rd.on('line', function(line){
console.log(line);
return_string += line;
});
return return_string;
}
};
Shouldn't the h3 tag read the data that is in the file I passed now? What is going wrong?
Upvotes: 0
Views: 2390
Reputation: 707446
load_blocks()
is asynchronous. It does not return the finished string because the readline code inside that function is asynchronous and has not yet finished when load_blocks()
returns so thus return_string
does not yet have the value you want when you return.
This is a classic asynchronous programming problem in Javascript. Your load_blocks function needs to either return a promise or call a callback when it finishes its work and the caller has to use that returned promise or callback to obtain the final result.
For a lot more info on returning an asynchronous value, see the various options offered here: How do I return the response from an asynchronous call?
You could change the code to something like this:
app.get('/', function(req, res){
blockchain.load_blocks().then(val => {
res.send('<h3>' + val + '</h3>');
}).catch(err => {
console.log(err);
res.status(500).end();
});
});
And, then change blockchain.load_blocks()
to return a promise that resolves when you have the final value.
The code you show for load_blocks
appears to just be reading an entire file. I don't understand any reason that you are reading it line by line. If you just want to read a whole file, you can just use fs.readFile()
to read the whole file.
module.exports = {
load_blocks: function() {
return new Promise((resolve, reject) => {
fs.readFile('/home/blockchain_data/1.dat$', function(err, data) {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
};
Upvotes: 2