简体   繁体   中英

Node.js stream difficulties

**Edited: This is the form code I am using currently. I basically took it
from suggestions on stack overflow.

    app.post('/FunFun.js', function(req, res) {
    var file = req.params.value; 
console.warn(req.params);
console.warn(req.params.value);
    var fileContent = JSON.stringify(file);


    fs.appendFile('Focus.txt', fileContent + '\n', function(err) {
    if (err) {
        console.log('Failed to append to the file! ', err)
    } else {
        console.log('Appended data to file!');
    }
    res.render('Form.html');

     });
     });

So, I am trying to basically read form values from a survey(multiple choice) I created with HTML into a Stream in my Node.js file in order to save the values of each participant in a txt file( I know a database is preferable, this is for college). So here is my Node.js file:

var express = require('express');
var app = express();
var path = require('path');
var fs = require('fs');
var bodyParser = require('body-parser');
var engines = require('consolidate');

app.set('views', __dirname + '/Desktop');
app.engine('html', engines.mustache);
app.set('view engine', 'html');

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));


app.get('/', function(reg, res) {
    res.render('Form.html');
});

app.post('/FunFun.js', function(req, res) {
    res.render('Form.html');
    var file = req.body; //req.params.values;
    filecontent = JSON.stringify(file);

    var stream = fs.createWriteStream("Focus.txt", {
        objectMode: true
    }); //{'flags': 'a'});
    stream.on('open', function() {
        stream.write(filecontent);
        stream.end();
    });
});

var server = app.listen(8080, function() {
    console.log('Server listening on port 8080');
});

I would post my form, but it is a standard multiple choice questionnaire type form with radio buttons. Anyways, I want to save the users choice in a file, and to me it seems that my NOde.js file should do the trick, but I keep getting this error:

TypeError: Invalid non-string/buffer chunk

So I know that streams apparently cannot usually handle data other than strings and buffers. However, I thought JSON.stringify would do the trick. However, it isn't. I am new to Node.js and express, so wondering if anyone has any ideas on what I am missing?

Xtra: Decided to show a sample of my HTML form just for emphasis. I am trying to extract the value of the radio button selected.

   <form  action = "/FunFun.js" method = "post" style = "border : 2px   
    solid black;">
 .......

<table>
    <tr>
        <td colspan="1">7</td>
        <td colspan="8">If I had more time, I would have done better in this course.</td>
        <td colspan="16">
            <table style="width: 100%;">
                <tr>
                    <td><input id="g1" name="GroupG" onclick="groupG()" type="radio" value="1std"></td>
                    <td><input id="g2" name="GroupG" onclick="groupG()" type="radio" value="1sod"></td>
                </tr>
            </table>
        </td>
        <td><input id="g3" name="GroupG" onclick="groupG()" type="radio" value="1neu"></td>
        <td colspan="16">
            <table style="width: 100%;">
                <tr>
                    <td><input id="g4" name="GroupG" onclick="groupG()" type="radio" value="1sta"></td>
                    <td><input id="g5" name="GroupG" onclick="groupG()" type="radio" value="1soa"></td>
                </tr>
            </table>
        </td>
    </tr>
</table>

.....
<td colspan = 100%> <input type="submit" value="submit" formaction 
  = "/FunFun.js"> <input type="reset" onClick = "resetB()">   </td>

</tr>


</table>

If you take a look at the documentation for fs.createWriteStream , you'll see that there is no objectMode in the valid options. objectMode is not documented, because even though the underlying stream.Writable class does support the feature, the fs.WriteStream does not. For a good reason - how would it choose how to serialize the objects you've given it? How should it represent { a:1 } ? In textual JSON? In some binary format? Exactly. That's up to the programmer to choose.

Additionally, the POST handler is writing a response to the client (in HTML) before actually appending to the file ( res.render(...) ). I would suggest moving this to the success callback of the write, so that you actually do the operation before returning results.

So, remove the objectMode from the options and move the res.render(...) and the write works. Remember that when working with streams which do not operate in object mode, you can only write strings, Buffer s or Uint8Array s , so you're correct in using JSON.stringify first.

By the way, unless you're streaming directly from the client to the file, which would probably require you to stream the JSON transform on the fly somehow, you'd probably be better off using fs.appendFile or fs.writeFile . They have a simpler API which I think you might want:

app.post('/FunFun.js', function(req, res) {
    var file = req.body; // req.params.values;
    var fileContent = JSON.stringify(file);

    fs.appendFile('Focus.json', fileContent + '\n', function(err) {
        if (err) {
            console.log('Failed to append to the file! ', err)
        } else {
            console.log('Appended data to file!');

        }
        res.render('Form.html')
    });
});

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