Reputation: 1365
I'm trying to post form data in another view in my node/express application. I'm using Jade as the view engine.
My question is how do I access this res.body object? How to I get at the data? I'm trying to use user input to draw some graphs.
Code below
barchartEntry.jade
form(method="POST")
#dynamicInput
input(type="button" value="Add New Bar" onClick="addInput('append');")
input(type="button" value="Remove Last Bar" onClick="removeInput();")
br
label(class="barTitle") Bar 1
label(class="bartTtle") Value
input(type="text" name="myInputs[]")
label Label
input(type="text" name="myLabel[]")
br
#append
input(type="submit" value="Submit")
include copyright
Route Handler
exports.postBarchartentry = function postBarchartentry(req, res){
res.body = req.body;
res.render('barchart');
};
local JS on new view
$( document ).ready(function() {
var values = ?
var labels = ?
var canvas = document.getElementById("canvas").getContext("2d");
var Width = canvas.canvas.clientWidth;
var Height = canvas.canvas.clientHeight;
var padding = 30;
function fillBackground(color){
canvas.fillStyle=color;
canvas.fillRect(0,0,Width,Height);
}
function fillAxes(){
canvas.beginPath();
canvas.moveTo(padding, padding);
canvas.lineTo(padding, Height-padding);
canvas.lineTo(Width-padding, Height-padding);
canvas.lineWidth = "3"
canvas.strokeStyle="black";
canvas.stroke();
}
function draw(){
fillAxes();
}
draw();
});
As you can see, I'm trying to get the inputted form data to be accessable in my last script
Upvotes: 1
Views: 1467
Reputation: 6433
Hector is correct in that the view only has access to what you pass directly into it. So the question remains what do you want to pass into it?
req.body
is indeed a JavaScript object, and your markup gives a really nice way to get at the contents.
I put together a little test project where I used your markup:
label(class="barTitle") Bar 1
label(class="bartTtle") Value
input(type="text" name="myInputs[]")
label Label
input(type="text" name="myLabel[]")
When I submitted that form, in my post handler I had something like this:
app.post('/arraytest', function(req,res) {
console.log(req.body)
res.send(req.body)
})
(We'll ignore for now the ugliness of putting the actual handler inline with the routing call). When that form submits, I get this object for req.body
:
{ myInputs: [ '3' ], myLabel: [ 'asdf' ] }
For fun, I added a second input box and pluralized myLabel
, so that my form looked like this:
label(class="barTitle") Bar 1
label(class="bartTtle") Value
input(type="text" name="myInputs[]")
label Label
input(type="text" name="myLabels[]")
label(class="barTitle") Bar 2
label(class="bartTtle") Value
input(type="text" name="myInputs[]")
label Label
input(type="text" name="myLabels[]")
Notice that I didn't change any of the names. I left them with the array brackets at the end. Submitting this form gave me the following object:
{ myInputs: [ '3', '4' ], myLabels: [ 'asdf', 'asdfasfsdf' ] }
So the interaction between the browser and body parsing gives you two arrays with all of your values. Arrays are easy enough to loop over. If you modify your render call to look like:
res.render('barchart', {inputs: req.body.myInputs, labels: req.body.myLabels})
then in your view you can have something like:
- each input, i in inputs
= input
= myLabels[i]
But since you want this accessible in your JS, you can use this in your Jade:
script.
var inputs = !{JSON.stringify(inputs)}
, labels = !{JSON.stringify(labels)}
alert(inputs)
alert(labels)
You'll likely not need the alert
calls, but I put them there to convince me that it worked.
Many thanks to this SO question and answer for the dynamic JS portion: How can I render inline JavaScript with Jade?
Upvotes: 2
Reputation: 26680
My question is how do I access this res.body object? How to I get at the data?
You'll have access to this data in your controller as you indicated. If you want to pass this data to another view you need to explicitly pass it to the next view.
exports.postBarchartentry = function postBarchartentry(req, res){
res.render('barchart', {data1: req.body.field1, data2: req.body.field2});
};
In your barchart view you have two options. (1) you can render HTML directly (via Jade) with the new data. For example, add a div if data1 has data. (2) you can also render JavaScript on the page (again via Jade) so that those values will be available when the browser execute the onReady which I think is what you are trying to do.
Also, make sure you are using Express' bodyParser middleware somewhere in your application so that req.body.X has the actual data:
app.use(express.bodyParser())
Upvotes: 2