Personal Library Project - getting API routes to work with req.params.id

Hello FCC Forum!

I am wondering if I can get a code review on my Personal Library Project and perhaps some pointers why my routes using req.params.id aren’t work. You can see My GLITCH project here. Currently my issue is:

All routes act like app.route('/api/books') and when I attempt to pass a book ID to app.route('/api/books/:id') via a parameter or I’ve even tried with req.body, the ID isn’t received and the route behaves as if I never provided an ID.

My design choice was to not use separate model or controller files as I wanted to put all the functionality in the api.js file as this is a pretty simple set of functionality. Many of the examples I saw went with the MVC design approach, so perhaps that’s what is causing my issue?

Hi!
There could be something wrong with the line

const {_id} = req.params.id

You’re using destructuring here with the {_id}. This would only work if req.params.id would be an object with a key _id. So if you’d instead just write

const id = req.params.id

your routing might work.

1 Like

Thanks for the suggestion, I tried that and the same problem occurs.

Strange… can you use some console output to check which routes are used and if the parameter id is defined?
Also in server.js there is a single

app.use

between the bodyParser and the cors middleware. That seems a bit odd.

1 Like

Thanks for pointing that out, i removed that line. I console.log both doc and id, and id is never returning on those requests. So It’s like the ID is never being passed through. I’ve added the log statements to each request on GLITCH if you want to check out where I placed those. I’m wondering if it has anything to do with how Mongo created IDs as such _id :thinking:

Right now the route says

app.route('/api/books/id')
   .get(function (req, res, next){
   const id = req.body.id; 

The first approach

app.route('/api/books/:id')
   .get(function (req, res, next){
   const id = req.params.id; 

should definitely work.
The _id of Mongo shouldn’t be a problem. The only bug that could give is when one would try something like Plan.find({id: myId}, ...) instead of Plan.find({_id: myId}, ...) or Plan.findById(myId, ...)

1 Like

Yeah I was playing around to see if the : was causing the problem. so now if pass in the request with an ID as such https://fcc-is-qa-personal-library-jv.glitch.me/api/books/: it works, with ID as a body parameter! this also fixed the other routes. So I have the ID in the body, which is fine for this example project. I’m not 100% clear on why the : is so important in this request. Can you explain that? Thanks for all the help!

It’s completely valid to send the id in the body. A parameter would just make the id visible in the url. You could directly go to a certain book by entering https://www.myLibrary.com/api/books/:5 https://www.myLibrary.com/api/books/5 (as @RandellDawson pointed out below)
By putting the id in the request body, only requests made from the front end js, e.g. by using fetch(...) will be able get the appropriate responses.
The colon in the route books/:id makes sure that the router recognizes the 5 as a parameter for the books route, rather than a dedicated “5 route”

1 Like

I could be totally wrong here, but I have not seen an API that forces the user to add a colon in front of a parameter. I would think the use of app.route(’/api/books/:id’) already makes it clear to express that a request made to https://www.myLibrary.com/api/books/5, would mean id would be assign the value 5. At least that is what I have always done in my applications.

2 Likes

You are absolutely right, of course. The colon belongs only to the route description, not the url.

@RandellDawson / @wutzig It works fine in the browser test with no : and I was testing with Postman directly to the API, and for some reason it just likes the : in the URL. the content/type is set to application/x-www-form-urlencoded not sure if that may be cause it.