Exercise Tracker API Calls Return 'Not Found'

Hi there,

I’ve been able to finish all of the API/Microservices projects but the Exercise Tracker one. I thought that I had express setup properly like on my other projects, but something isn’t right. When I navigate to the paths from my app.get() or app.post() calls my code should be making a console log and then returning a json object, but it doesn’t do either. Instead, it ends up loading a page with a white background and the phrase ‘not found’ displayed in the upper-right corner.

I’m working from the default glitch app that FCC gives you. I’ve added a .env file for my MongoDB uri and I’ve edited the package.json to use newer versions of express/mongoose/etc. Otherwise, all of my code is in the server.js file, so I’ve copied that below. Let me know if there’s any other information you could use.

Any thoughts you might have about what’s wrong with my app so far would be a huge help. Thanks!

const express = require('express')
const mongo = require('mongodb')
const mongoose = require('mongoose')
const bodyParser = require('body-parser')

const cors = require('cors')

const app = express()

mongoose.connect(process.env.MLAB_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true
}).then( () => {
  console.log('successfully connected');
},
err => {
  console.log('connection error: ', err);
});

app.use(cors())

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


app.use(express.static('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'})
})

// Error Handling middleware
app.use((err, req, res, next) => {
  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)
})

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





const userSchema = mongoose.Schema({
  userName: {type: String, required: true}
});
const user = mongoose.model('user', userSchema);

const exerciseSchema = mongoose.Schema({
  userId: {type: String, required: true},
  description: {type: String, required: true},
  duration: {type: Number, required: true},
  date: {type: String, required: false},
});
const exercise = mongoose.model('exercise', exerciseSchema);

app.post('/api/exercise/new-user', (req,res) => {
  console.log('test');
  res.json({note: 'test'});
});


app.get('/test', (req,res) => {
  console.log('test');
  res.json({note: 'test'});
});

From the looks of it, it’s probably because your 404 middleware is intercepting the GET /test and POST /api/exercise/new-user.

If you put your 404 middleware before your GET /, you’ll get the not found message too.

Looking at the Express docs, here’s an excerpt (refer to bolded + italicised):

In Express, 404 responses are not the result of an error, so the error-handler middleware will not capture them. This behavior is because a 404 response simply indicates the absence of additional work to do; in other words, Express has executed all middleware functions and routes, and found that none of them responded. All you need to do is add a middleware function at the very bottom of the stack (below all other functions) to handle a 404 response:

app.use(function (req, res, next) {
  res.status(404).send("Sorry can't find that!")
})

Add routes dynamically at runtime on an instance of express.Router() so the routes are not superseded by a middleware function.

I’m not an expert on Express but that’s what I understand based on this Glitch.

You should put your code before the Not found middleware.

That looks to be it. Thanks so much @wanzulfikri and @LucasChau. You just saved me a few hours of head scratching.

1 Like