Apis and Microservices Projects - Exercise Tracker Post request returning [object Object]

Hi,

I’ve just started with this project and can’t seem to get body parser to send the data from the form in req.body.username. It just keeps returning [object Object] every time no matter what I change in the configuration. I have searched online but nothing has helped.

Here is the server file -

const app = express()
const bodyParser = require('body-parser')
const cors = require('cors')
const mongoose = require('mongoose')
var mongo = require("mongodb");


//Connect to mongoose DB
process.env.MONGOLAB_URI = "mongodb://wade:helloworld1@ds125293.mlab.com:25293/mydatabase";
mongoose.connect(process.env.MONGOLAB_URI,{ useNewUrlParser: true }|| 'mongodb://localhost/exercise-track' )


//Install middleware
app.use(cors())
app.use(bodyParser.urlencoded({extended: true }))
app.use(bodyParser.json())
app.use(express.static(__dirname + '/public'));


app.get('/', (req, res) => {
  res.sendFile(__dirname + '/views/index.html')
});



// Not found middleware
app.use((req, res, next) => {
  return next({status: 404, message: 'not found'})
})


app.post('/api/exercise/new-user', (req, res) =>{
 
 res.json({name:req.body.username})
})
// Error Handling middleware


//create a user by posting form data username to /api/exercise/new-user and returned will be an object with username and _id.

  

//get an array of all users by getting api/exercise/users with the same info as when creating a user.


//add an exercise to any user by posting form data userId(_id), description, duration, and optionally date 
//to /api/exercise/add. If no date supplied it will use current date. Returned will the the user object with 
//also with the exercise fields added.


//I can retrieve a full exercise log of any user by getting /api/exercise/log with a parameter of userId(_id).
//Return will be the user object with added array log and count (total exercise count).



 app.listen(process.env.PORT || 3000, () => {
  console.log('Your app is listening on port ')
})



And the HTML page-

<!DOCTYPE html>
<html>

   <head>
      <title>Exercise Tracker | Free Code Camp</title>
      <link rel="shortcut icon" href="https://cdn.hyperdev.com/us-east-1%3A52a203ff-088b-420f-81be-45bf559d01b1%2Ffavicon.ico" type="image/x-icon"/>
      <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet" type="text/css">
      <link href="style.css" rel="stylesheet" type="text/css">
   </head>

   <body>
      <div class="container">
         <h1>Exercise tracker</h1>
          <form action="/api/exercise/new-user" method="POST">
            <h3>Create a New User</h3>
            <p><code>POST /api/exercise/new-user</code></p>
            <input id="uname" type="text" name="username" placeholder="username">
            <input type="submit" value="Submit">
          </form>
          <form action="/api/exercise/add" method="post">
            <h3>Add exercises</h3>
            <p><code>POST /api/exercise/add</code></p>
            <input id="uid" type="text" name="userId" placeholder="userId*">
            <input id="desc" type="text" name="description" placeholder="description*">
            <input id="dur" type="text" name="duration" placeholder="duration* (mins.)">
            <input id="dat" type="text" name="date" placeholder="date (yyyy-mm-dd)">
            <input type="submit" value="Submit">
          </form>
          <p><strong>GET users's exercise log: </strong><code>GET /api/exercise/log?{userId}[&amp;from][&amp;to][&amp;limit]</code></p>
          <p><strong>{ }</strong> = required, <strong>[ ]</strong> = optional</p>
          <p><strong>from, to</strong> = dates (yyyy-mm-dd); <strong>limit</strong> = number</p>
      </div>
   </body>

</html>

You may want to try changing your Not Found handler so it sends the JSON object instead of calling next and see if that works:

// Not found middleware
app.use((req, res, next) => {
  res.json({status: 404, message: 'not found'})
})

Edit: may not have read your post closely enough - if you are seeing the Object displayed as [object Object] in text on a new page, you may want to create an event listener on your front-end to handle the post action manually, rather than having the form do the work. That way you can handle the return response as needed rather than being redirected to the form action URL.

Thank you.That is exactly what it was. I just had to remove the middleware handler. I really should of seen that. This community is amazing.

I realize that this post is several months old now, but did you end up rewriting any of the middleware handler? I ran into the same problem/ solution independently: I could not get any of the post methods to print anything to the console, and the middleware was interrupting it. Did you end up identifying where it was going wrong?

@madisonMaxm It was a few months ago but from memory I think that the not found pre written code does not need to be there and csuses the issue. I think I just removed it.

app.use((req, res, next) => {
  return next({status: 404, message: 'not found'})
})

2 Likes

Just throwing the ‘not-found’ middleware away should feel wrong. Think about what’s happening with the middleware in the code as given in the original post. According to the Express.js documentation (and one or two of the fCC ‘APIs and Microservices’ exercises), the order in which the middleware functions are written in the server.js file matters:

The order of middleware loading is important: middleware functions that are loaded first are also executed first.
Writing middleware for use in Express apps

This means before the POST method in the above code can fire, the ‘not-found’ middleware is going to fire and return something that says something important hasn’t been found. Logically speaking, this should seem bad. Changing the order of things, meaning putting the ‘not-found’ middleware in a spot where it fires after an attempt to get information from the user (POST method in this case), seems prudent. And, in fact, not doing so means the POST method never fires. You can verify this by logging things to the console to see which methods are firing and in what order.

Also, if you add in the error-handling middleware after the ‘not-found’ middleware:

app.use((err, req, res, next) => {
  console.log(err);
  let errCode, errMessage

  if (err.errors) {
    // mongoose validation error
    errCode = 400 // bad request
    const keys = Object.keys(err.errors)
    // report the first validation error
    errMessage = err.errors[keys[0]].message
  } else {
    // generic or custom error
    errCode = err.status || 500
    errMessage = err.message || 'Internal Server Error'
  }
  res.status(errCode).type('txt')
    .send(errMessage)
})

and check out what it logs to the console, you’ll see:
{ status: 404, message: 'not found' },
which shows the importance of keeping not only the ‘not-found’ middleware, but also the error-handling middleware. Again, though, both of these middlewares should go after the POST method.

4 Likes