Reputation: 19
**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>
Upvotes: 0
Views: 159
Reputation: 13632
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')
});
});
Upvotes: 2