Get Data from POST Requests

Hey campers,

I am just going through API challenges and I am at Get Data from POST Requests

When I run the code, I am getting the following error:

// running test
Test 1: "POST /name" route does not behave as expected
Test 2: "POST /name" route does not behave as expected
// tests completed

Here is my code and what I have ; I am not sure what I have done wrong or what I am missing.


var express = require('express');
var app = express();
var bodyParser = require('body-parser');
const path = require('path')

// --> 7)  Mount the Logger middleware here
app.use((req, res, next) => {
console.log(req.method + ' ' + req.path + ' ' + '-' + ' ' + req.ip)
next()
})

// --> 11)  Mount the body-parser middleware  here
app.use( bodyParser.json() );       // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
  extended: true
})); 

/** 1) Meet the node console. */
app.use('*', (req, res, next) => {
console.log('Hello World')
next()
})

/** 2) A first working Express Server */
//app.get('/', function (req, res) {
//  res.send('Hello Express')
//})

/** 3) Serve an HTML file */
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, './views/index.html'))
})

/** 4) Serve static assets  */
app.use('/', express.static(path.join(__dirname, 'public')))

/** 5) serve JSON on a specific route */
app.get('/json', (req, res) => {
  let message = 'Hello json'
  if (process.env.MESSAGE_STYLE === 'uppercase') {
    return res.json({"message": message.toUpperCase()})
  }
  return res.status(200).json({"message": message})
})

/** 6) Use the .env file to configure the app */
 var message ="Hello json";
var msgObj ={};
msgObj = {"message":message};
    if(process.env.MESSAGE_STYLE=="uppercase")
    {
      message = message.toUpperCase();
      msgObj.message = message;
    }
      
    app.get("/json", function(req, res) {
      return res.json(msgObj);
      });
 
/** 7) Root-level Middleware - A logger */
//  place it before all the routes !


/** 8) Chaining middleware. A Time server */
app.get('/now', (req, res, next) => {
  req.time = new Date().toISOString()
 
  next()
}, (req, res) => {
  res.status(200).json({"time": req.time})
})

/** 9)  Get input from client - Route parameters */
app.get('/:word/echo', (req, res) => {
  res.status(200).json({"echo": req.params.word})
})

/** 10) Get input from client - Query parameters */
//
// /name?first=<firstname>&last=<lastname>
app.route('/name').get((req, res) => {
  res.status(200).json({"name": req.query.first + ' ' + req.query.last})
   
}).post((req, res) => {
  res.status(200).json({"name": req.query.first + ' ' + req.query.last})
})
  
/** 11) Get ready for POST Requests - the `body-parser` */
// place it before all the routes !


/** 12) Get data form POST  */
app.post('/name', (req, res) => {
  let name = req.body.first + ' ' + req.body.last;
  res.json({name: 'firstname lastname'});
});


// This would be part of the basic setup of an Express app
// but to allow FCC to run tests, the server is already active
/** app.listen(process.env.PORT || 3000 ); */

//---------- DO NOT EDIT BELOW THIS LINE --------------------

 module.exports = app;

Thank you ahead for any help !!!

1 Like

Maybe itā€™s because youā€™re responding with the hardcoded 'firstname lastname' string? Try replacing that string with the name variable.

Hi @kevcomedia

I tried your advice

app.post('/name', (req, res) => {
  let name = req.body.first + ' ' + req.body.last;
  res.json({name: 'name'});
});

ā€¦ and it is still giving me the same error.

Mind you, itā€™s 2AM here so I am a bit tired ; I might be misreading what you wrote.

Itā€™s still a hardcoded string. I meant the name variable that you made right before calling res.json, like

res.json({name: name});

If that doesnā€™t work then I might be mistaken.

EDIT: Thereā€™s an earlier POST handler for the /name route in your code (the one attached to app.route('/name'). Thatā€™s the one being used in your code.

Same error, with this code:

app.post("/name", urlencodedParser, function(req, res) {
  let naamke = req.body.first + " " + req.body.last;
  res.json({'name':naamke});
});

Help appreciated! :slight_smile:

Your code passed when I tried it, but instead of using the urlencodedParser middleware just in that one route handler, I mounted it using app.use()

@kevcomedia

I am now more confused than what I was at 2AM last night.

Please, clarify what you meant in your previous post.

Yeah, would you mind sharing some code?

@BoCode84

I meant that in your code, thereā€™s actually 2 POST handlers for the /name route.

This:

/** 10) Get input from client - Query parameters */
//
// /name?first=<firstname>&last=<lastname>
app.route('/name').get((req, res) => {
  res.status(200).json({"name": req.query.first + ' ' + req.query.last})
}).post((req, res) => {
  res.status(200).json({"name": req.query.first + ' ' + req.query.last})
})

and this:

/** 12) Get data form POST  */
app.post('/name', (req, res) => {
  let name = req.body.first + ' ' + req.body.last;
  res.json({name: 'firstname lastname'});
});

It so happens that when you make a POST request on the /name route, it uses the first one, which always respond with {"name": "undefined undefined"} (or something similar, I canā€™t remember exactly). Try removing the first POST handler, then modify the second one so that it returns the value that you saved in the name variable.

app.post('/name', (req, res) => {
  let name = ...;
  res.json({name: name});
});

@R4FKEN

Does your code have this part near the beginning?

app.use(bodyParser.urlencoded({extended: false}));

With the amount of code that you posted, I can only guess. Can you share the entire code?

@kevcomedia It has this line somewhere:

var urlencodedParser = bodyParser.urlencoded({extended:false});

The ā€œurlencodedParserā€ then gets used in my ā€œapp.postā€, right?

Yet when I run the tests, it returns:

// running test
Test 1: "POST /name" route does not behave as expected
Test 2: "POST /name" route does not behave as expected
// tests completed

and

Test 1 : Your API endpoint should respond with the correct name
Test 2 : Your API endpoint should respond with the correct name

:sob:

If you have urlencodedParser declared as such in your code, then the POST handler that you posted earlier should pass.

By any chance does your code have another POST handler for /name (like in BoCode84ā€™s) example?

No, I checked that. Would you mind taking a look? https://glitch.com/edit/#!/join/357b9a82-05b0-4c37-99ba-ec5029b9b601

The part right below where you declared urlencodedParser is somehow interfering with the POST request:

app.use("/", urlencodedParser, function(req, res) {
  res.send(req.body);
});

That route is whatā€™s being used when you make a POST request to /name. I donā€™t know why thatā€™s the case. Removing it should allow you to pass.

1 Like

Thanks, commenting that part out, solves the problem! I wouldā€™ve never figured that one outā€¦

Thank you ! That did it ;

Lesson learned: Donā€™t try your projects at 2AM :slight_smile:

Thank you guys! I did it using your approach.

Is that possible to do it without defining a variable? By putting this at the top?

app.use(bodyParser.json());
app.use( bodyParser.urlencoded({extended: false}));


app.post('/name',function(req,res){
  // console.log('i am in app post', req.body);
  res.json({"name" : req.body.first +' '+req.body.last});
});

Can anyone please, explain why above does not work and how to fix it?

2 Likes

Hello how can i post on the front page HTML without building a post request on the submit button

Yes, itā€™s fine to define at top instead of storing it to a variable.

app.use(bodyParser.urlencoded({ extended: true }));
app.post(ā€™/nameā€™,function(req,res){

var jsonObj=req.body.first+ā€™ ā€˜+req.body.last;
res.send({name:jsonObj});
console.log(req.body.first+ā€™ '+req.body.last);

})

app.get(ā€™/ā€™, function(req, res) {
res.sendFile(path.join(__dirname + ā€˜/views/index.htmlā€™));
});

This works for me
/** 12) Get data form POST  */
app.post('/name', function(req, res) {
  var firstName = req.body.first;
  var lastName = req.body.last;
  res.send({"name": `${firstName} ${lastName}`});
});
1 Like