FAQ: Router Parameters - Merge Parameters

This community-built FAQ covers the “Merge Parameters” exercise from the lesson “Router Parameters”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Web Development

Learn Express

FAQs on the exercise Merge Parameters

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

I’m lost in the Learn section of this lesson.

The explanation of the example code isn’t clear about which part of the code each sentence refers to.

Which line of code is referred to by the sentence “The familiars are nested into the sorcerer endpoint — indicating the relationship that a sorcerer has multiple familiars”? Is it sorcererRouter.use('/:sorcererId/familiars', familiarRouter);?

Which line of code tells Express that “the path for the familiarRouter is the same as the path for the sorcererRouter with the additional path /:sorcererId/familiars”? Is it also sorcererRouter.use('/:sorcererId/familiars', familiarRouter);?

Which line of code “create(s) a family of routes (a router) built by appending routes to familiarRouter‘s base: /sorcerer/:sorcererId/familiars”? Is it also sorcererRouter.use('/:sorcererId/familiars', familiarRouter);? Or app.use('/sorcerer', sorcererRouter);?

14 Likes

This topic is very confusing.Unable to understand how the parent and nested routers are connecting.
like in the exercise its confusing how app.js is nested with spiceRouter.and we make this line of code for router variable.
const router = require(‘express’).Router({ mergeParams: true });

Can someone explain the whole concept here.the lesson is not very helpful in understanding the code.

thanks

7 Likes

After finishing the Express.js tutorial, I think I now understand this lesson’s code more or less. Let me try to explain it below.

const sorcererRouter = express.Router();                      // Line 1
const familiarRouter = express.Router({mergeParams: true});   // line 2
sorcererRouter.use('/:sorcererId/familiars', familiarRouter); // line 3

These three lines establish the following: (1) familiarRouter is a child router of sorcererRouter and its root path is /:sorcererId/familiars (by line 3); (2) familiarRouter will share parameters available for sorcererRouter (by lines 2-3).

sorcererRouter.get('/', (req, res, next) => { // line 4
  res.status(200).send(Sorcerers);            // line 5
  next();                                     // line 6
});                                           // line 7

Lines 4-7 specify how to respond to the GET requests for sorcererRouter's root path (which will be set as /sorcerer in line 16 below).

sorcererRouter.param('sorcererId', (req, res, next, id) => { // line 8
  const sorcerer = getSorcererById(id);                      // line 9
  req.sorcerer = sorcerer;                                   // line 10
  next();                                                    // line 11
});                                                          // line 12

For requests sent to the path /:sorcererId, retrieve the data (line 9) and pass it as req.sorcerer to the next middleware (lines 10-11).

familiarRouter.get('/', (req, res, next) => { // line 13
  res.status(200).send(`Sorcerer ${req.sorcerer} has familiars ${getFamiliars(sorcerer)}`); // line 14
}); // line 15

For GET requests sent to the path /:sorcererId/familiars (the root path for familiarRouter as set by line 3 above), send a message (I’m not sure of this way of using send(), though) that includes req.sorcerer. This is possible because, thanks to line 2 above, familiarRouter has access to req.sorcerer which is a parameter for sorcererRouter (created in line 10 above).

In passing, I have no idea what ${getFamiliars(sorcerer)} is. Perhaps it’s a function defined somewhere else. I also think this is the least helpful example of how a parent router’s parameters can be shared by its child router, because (1) we haven’t learned how to use send() with a string as an argument; (2) it’s not clear what req.sorcerer contains; (3) there’s no explanation whatsoever about getFamiliars(sorcerer).

Well, let’s move on to the last line of code.

app.use('/sorcerer', sorcererRouter); // line 16

Any request sent to the path /sorcerer will be dealt with by sorcererRouter. I think this line of code should come at the top, right after we have defined sorcererRouter in line 1, for code readability. Another source of confusion…

25 Likes

I think this particular exercise needs rewriting tidying up. Apart from the confusing content described above, there are errors in the exercise steps, for example:

Each file has a param method call ( app.param in app.js , router.param in spicesRouter.js ).

Unless I’m missing something, there’s no param method call in spicesRouter.js.

12 Likes

That got me confused either.

3 Likes

I have finished the exercise, but cannot understand the meaning of number 3: make sure to set the newSpice.spiceRackId equal to the req.params.spiceRackId, as I cannot see any reference to this variable in other places.
Thanks!

4 Likes

Thank you for writing a step-by-step explanation!

spiceRackId is used in app.js:

app.param('spiceRackId', (req, res, next, id) => {
  const idToFind = Number(id);
  const rackIndex = spiceRacks.findIndex(spiceRack => spiceRack.id === idToFind);

It takes the name id in the callback function.

Anyway, in spicesRouter.js, here is how to set that attribute:

  const newSpice = req.body.spice;
  newSpice.spiceRackId = Number(req.params.spiceRackId);

At first I tried const newSpice.spiceRackId = ..., but that’s wrong because we’re not defining a new variable but rather setting an attribute on newSpice.

5 Likes

Thank you so much for explaining this line by line - I doubt I would have been able to figure it out on my own otherwise!

I don’t understand why we would need to access previous params in the exercise or example given, couldn’t we just assign them as properties to the req object using app.param() and access them that way?

Thanks a lot, @masakudamatsu for your detailed explanation
I also doubt that the last line

app.use('/sorcerer', sorcererRouter);

Should come first as you said.

I don’t understand why I can’t just use req.spiceRackIndex that was assigned by the app.param() in app.js if it’s a step ahead of the spicesRouter.post() route and assign it to the newSpice.spiceRackId instead of using req.params.spiceRackId. I mean with app.param I’m taking charge of all ‘/spice-racks/:spiceRackId’ routes which is a step ahead of '/spice-racks/:spiceRackId/spices/ that’s used in spicesRouter.post(). So why would I need to use req.params.spiceRackId if that’s the purpose of req.spiceRackIndex?

@masakudamatsu thanks for the explanation. I am trying to understand Express as best I can, but this course through Codecademy is not well instructed.

4 Likes

@anydavenow yeah this course needs an overhaul… I am not liking this Express course which is disappointing because I was excited to learn it.

8 Likes

I agree I am very disappointed by the standard of instruction throughout this whole section. Glad to see I am not the only one who feels this way. Clearly if feedback is taken seriously, they should modify the layout and the writing of the content.

9 Likes

This is an example of how codecademy should set up its explanations for clarity and so that they are learner friendly.

1 Like

I also found this lesson very confusing and agree that it would seriously benefit from a rewrite.

7 Likes

I honestly thought was going mad. And found it very demotivating. Found so many typos too. The course needs to be revamped, the instructions are not very clear. I’m disappointed.

9 Likes

As others have mentioned, this lesson especially needs to be rewritten. It has caused me so much frustration. This express lesson in total is quite a failure - it makes me want to quit learning to code.

9 Likes