简体   繁体   中英

Node.js cannot pass string into res.send(); Undefined

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?

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);
                 }
             });
         });
     }
 };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM