9

I am new to Express and Mongoose. I am currently working on my first project, that is not a tutorial, and I has run into a problem.

I have multiple routes, they are defined in the index.js like this:

app.use('/api/client',require('./routes/client'));
app.use('/api/host',require('./routes/host'));

In the routes, there are multiple verbs that work, like PUT and POST. Here is the problematic route (I am trying to do more that what is presented here, but what is presented here, does not work as well):

router.get('/ama/:id', function (req, res, next) {
    Ama.findById(req.params.id).then(function(Ama){
        res.send(Ama);
    });
});

This should work, right? It should return the document in the database, with that id. And I have checked if the document excists, probably around a 100 times. Now, if I simplify the route greatly, removing the id, and make a simple response, the route works:

router.get('/ama', function (req, res, next) {
    res.send({type:"GET"});
});

It's so wierd, that as soon as i add the parameter, i get a:

<pre>Cannot GET /api/host/ama</pre>

in Postman.

Any ideas? Mongod is running, my other routes are working.

Andreas
  • 117
  • 1
  • 1
  • 9
  • Where do you make the call to /api/host/ama ? Just using Postman? When you log req.params.id what do you get? – Cédric De Dycker Apr 04 '17 at 13:36
  • @CédricDeDycker Yes, I use Postman for now. I can't log req.params.id, because it seems like the code in the route is never even running in the first place. At least when I tried to log it, nothing happend. – Andreas Apr 04 '17 at 14:00

3 Answers3

17

It looks like you're trying to retrieve this URL:

/api/host/ama?id=SOMEID

However, you have a route declared for URL's that look like this:

/api/host/ama/SOMEID

In other words, the id is part of the path of the URL, and not passed as a query string parameter (that's what /:id means: it's a placeholder for a part of the URL that the route should match).

So either change the request-URL by adding the id to the path (/api/host/ama/58e395a8c6aaca2560089c‌​e7), or rewrite your route handler to something like this:

router.get('/ama', function (req, res, next) {
    Ama.findById(req.query.id).then(function(Ama){
        res.send(Ama);
    });
});

However, I would advise using the former (making the id part of the URL).

robertklep
  • 198,204
  • 35
  • 394
  • 381
  • I think you should read my question again. It seems like you solution is already the one I am trying to implement. – Andreas Apr 04 '17 at 14:27
  • @AndreasKristensen if you have a route `/api/host/ama/:id`, how come the error says that you're retrieving `/api/host/ama` (without any id)? – robertklep Apr 04 '17 at 14:28
  • I don't know. Here is the url I am using: `http://localhost:5000/api/host/ama?id=58e395a8c6aaca2560089ce7` – Andreas Apr 04 '17 at 14:32
  • Thank you for the edit, It works now. I am trying to learn here, so can you tell me, why this other route is have: `router.post('/question/:id',function(req,res,next){ Ama.findByIdAndUpdate( {_id:req.params.id}, {$push:{"qanda": req.body}},{safe:true,upsert:true} ).then(function(question){ res.send(question.qanda); }); });` Works with the id as a parameter? Is it becuase it's a POST request? – Andreas Apr 04 '17 at 14:37
  • @AndreasKristensen so you're posting to `/api/host/question?id=XXX`? It doesn't make sense that that would work, since the id is _required_ to be in the URL (otherwise that route would not match). – robertklep Apr 04 '17 at 14:41
  • I am not so sure now, I think it did when I tried it earlier today, but I am not sure. I think we should just leave this thread as it is. – Andreas Apr 04 '17 at 15:35
1

There are two problems here:

router.get('/ama/:id', function (req, res, next) {
    Ama.findById(req.params.id).then(function(Ama){
        res.send(Ama);
    })
    res.send(req.params.id)*/
});

First of all, res.send(req.params.id) will run before the res.send(Ama); and it will probably send the entire response. You are missing the .exec() method call (see the answer by Cédric De Dycker for details). The res.send() can only be reliably used once. Maybe you want res.write() instead if you want to wrte multiple things. Also you don't handle the promise rejection so you don't handle database errors. To know why you should always handle the promise rejections see this answer: Should I refrain from handling Promise rejection asynchronously?

Community
  • 1
  • 1
rsp
  • 107,747
  • 29
  • 201
  • 177
0

The parameter should work fine but it seems you missed to add .exec to your query

Ama.findById(req.params.id).exec().then(function(Ama){
      res.send(Ama);
 })