2

Goal:

The goal is to render data from the form where you enter your name and band. Once you submit you will be redirected to a new page which will state

Name: John Doe
Favorite Band: The Who

Problem:

I cannot use the express module for this exercise and I got it to render the data but it comes out like this on the page:

Your name is: name=John+Doe&band=The+Who
Your favorite band is: name=John+Doe&band=The+Who

I do realize that I am looking for something like body.name and body.band but I keep getting error messages.

What I have tried:

I have tried body-parser and query string but most of the examples I have found in researching have all dealt with being able to use express I am struggling with the translation.

What I am asking for:

I just need some guidance on how to solve this.

Here is my html file:

<!DOCTYPE html>
<html>
<head>
    <title>Welcome to my post form!</title>
</head>
<body>
 <div class='container'>
   <div class='jumbotron text-center'>
     <h1>Please post using this form:</h1>
   </div>
   <div class="row">
     <div class="col-sm-12 text-center">
       <form action="http://localhost:3000/thanks" method="POST">
        <input name="name" placeholder="enter your name">
        <input name="band" placeholder="enter your favorite band">
        <button type='submit'>submit</button>
      </form>
    </div>
  </div>
</div>
</body>
</html>

Here is my server.js file and what I currently have that works but gives me the output I showed above:

let http = require('http');
let fs = require('fs');
let server = http.createServer(handleRequest);
const port = process.env.PORT || 3000;
function handleRequest(req, res) {
var path = req.url;
if (req.method === "GET"){
  res.writeHead(200, {"Content-Type": "text/html"});
  fs.createReadStream("postalServiceHTML.html", "UTF-8").pipe(res);
  } else if (req.method === "POST" && path == '/thanks'){
  var body = "";
  req.on("data", function(chunk){
  body += chunk;
  });
}
  req.on("end", function(){
  res.writeHead(200, {"Content-Type": "text/html"})
  res.end(`
  <!DOCTYPE HTML>
  <html>
  <head>
  <title> Form Results </title>
  </head>
  <body>
  <h1> Your Form Results </h1>
  <p> Your name is: ${body} </p>
  <p> Your favorite band is: ${body} </p>
  </body>
  </html>
  `);
  });
}
 server.listen(port, () => console.log(Server is running on port ${port}));

3 Answers 3

1

Let me present working version:
postalServiceHTML.html - unchanged
Server - small changes:

var qs = require('qs');
let http = require('http');
let fs = require('fs');
let server = http.createServer(handleRequest);
const port = process.env.PORT || 3000;
function handleRequest(req, res) {
    var path = req.url;
    if (req.method == "GET") {
        res.writeHead(200, { "Content-Type": "text/html" });
        fs.createReadStream("postalServiceHTML.html", "UTF-8").pipe(res);
    } else if (req.method == "POST" && path == '/thanks') {
        var body = "";
        req.on("data", function (chunk) {
            body += chunk;
        });
    }
    req.on("end", function () {
        res.writeHead(200, { "Content-Type": "text/html" })
        if(this.method == "POST") {
            var json = qs.parse(body);
            res.end(`<!DOCTYPE HTML><html><head><title> Form Results </title></head><body>
                <h1> Your Form Results </h1><p> Your name is: ${json.name} </p>
                <p> Your favorite band is: ${json.band} </p></body></html>`);
        }
    });
}
server.listen(port, () => console.log(`Server is running on port ${port}`));

Possible to use qs ? It is used by body-parser too.

In case you have simple values like here and do not care about attempts to send some bad input, you can make it a single purpose for example like this:

var body = "name=John+Doe&band=The+Who%26Escape+test";
var strigified = '{' + body.replace(/([^=&]+)=/g, '"$1"='). // "name"=John+Doe&"band"=The+Who
                replace(/=([^&=]+)[&]*/g, ':"$1",'). // "name":"John+Doe","band":"The+Who",
                replace(/\+/g, ' '). // "name":"John Doe","band":"The Who",
                replace(/,$/g,'') + // "name":"John Doe","band":"The Who"
        '}';
var json = JSON.parse(unescape(strigified));
console.log(JSON.stringify(json, null, 2));

Sign up to request clarification or add additional context in comments.

1 Comment

Or split by & first and then again by =, that is hard to write as a "1-liner" (except IIFE ;-), but more reliable.
1

Here is a way a partner of mine helped me figure this out without using qs or body-parser

// Dependencies
const http = require("http");
const fs = require("fs");
const PORT = 7667;
const server = http.createServer(handleRequest);
function handleRequest(req, res) {
 const path = req.url;
 switch (path) {
 case "/thanks":
   return renderThankYouPage(req, res);
 default:
   return renderWelcomePage(req, res);
 }
}
function renderWelcomePage(req, res) {
 fs.readFile("./postalServiceHTML.html", function(err, data) {
   if (err) {
     res.writeHead(500, { "Content-Type": "text/html" });
     res.end("<html><head><title>Oops</title></head><body><h1>Oops, there was an error</h1></html>");
   }
   else {
     // We then respond to the client with the HTML page by specifically telling the browser that we are delivering
     // an html file.
     res.writeHead(200, { "Content-Type": "text/html" });
     res.end(data);
   }
 });
}
// Jay, you could even declare an array and use that as a temporary storage like this to keep track of all the inputs
let db = [];
function renderThankYouPage(req, res) {
 // Saving the request posted data as a variable.
   let requestData = "";
   // Variable declare to store the user inputs
   let userName;
   let bandName;
   let output;
 let myHTML =
       "<html><head><title>Hello Noder!</title></head><body><h1>Oops, I didn't get any data</h1></body></html>";
 // When the server receives data, it will add it to requestData.
 req.on("data", function(data) {
       requestData += data;
       // Parse the user inputs
       userName = data.toString().split('&')[0].split('=')[1].replace(/[+]/g, ' ');
       bandName = data.toString().split('&')[1].split('=')[1].replace(/[+]/g, ' ');
       // create a different user object for each input
       let userInput = {
           userName: userName,
           bandName: bandName
       }
       // Store into a dummy database - array
       db.push(userInput);
       console.log(userInput);
       console.log(db);
       // Generate the data to be render onto the client side
       for(let i = 0; i < db.length; i++) {
           output = <li> Name: ${db[i].userName} Band: ${db[i].bandName}</li>
           console.log(output);
       }
       console.log(output);
       // Content to be render back to client
   myHTML =
     "<html><head><title>Hello Noder!</title></head><body>" +
     "<h1>Thank you for the data: </h1> <code> " +
           output +
           "</code></body></html>";
 });
 // When the request has ended...
 req.on("end", function() {
   res.writeHead(200, { "Content-Type": "text/html" });
   res.end(myHTML);
 });
}
// Starts our server.
server.listen(PORT, function() {
 console.log("Server listening on: http://localhost:" + PORT);
});

1 Comment

Also interesting, voting up.
0

first you have to use body-parser to parse the body of the request and in your render html

  res.end(`
  <!DOCTYPE HTML>
  <html>
  <head>
  <title> Form Results </title>
  </head>
  <body>
  <h1> Your Form Results </h1>
  <p> Your name is: ${body.name} </p> // here a change
  <p> Your favorite band is: ${body.band} </p> // here a change
  </body>
  </html>
  `);
  });
}

if you dont want to use body parser, and you want just this example to work you could grab the name and favorite band from the body string... you have to find how

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.