FAQ: Learn Express Routes - Creating An Expression

This community-built FAQ covers the “Creating An Expression” exercise from the lesson “Learn Express Routes”.

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

Web Development

Learn Express

FAQs on the exercise Creating An Expression

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!

Hey @factoradic

In this exercise, the instructions are to use the ’ createElement(elementType, objectToCreate) helper function to create a valid expression. The first argument is the type of element, so it should be 'expressions' in this case. The second argument should be the query object with an emoji and a name property. ’

However in the solution, the parameters for createElement are

createElement('expressions', req.query);

How does the function know that req.query contains the correct parameters for name and emoji?

3 Likes

Hello :slight_smile:

That’s a really good question. createElement is just a helper function, just like you said. This function is not part of the Node.js or the Express, it’s just a function defined in this project to make it easier to manage the code.

So let’s take a look at this function and see if there are any mechanism that validate the second parameter passed to the function.

const { getElementById, getIndexById, updateElement,
        seedElements, createElement } = require('./utils');

This line tells us that functions getElementById, getIndexById, …, createElement are defined in the utils.js file. You can open this file using file explorer:

file_explorer

In this file you should find createElement function:

const createElement = (elementType, queryArguments) => {
  if (queryArguments.hasOwnProperty('emoji') &&
      queryArguments.hasOwnProperty('name')) {
    let currentId;
    if (elementType === 'expressions') {
      expressionIdCounter += 1;
      currentId = expressionIdCounter;
    } else {
      animalIdCounter += 1;
      currentId = animalIdCounter;
    }
    return {
      'id':    currentId,
      'emoji': queryArguments.emoji,
      'name':  queryArguments.name,
    };
  } else {
    return false;
  }
};

As you can see, this function starts with an if checking whether the second parameter has indeed properties emoji and name or not. If not (else block) function returns false.

This fact is used by the route controller here:

app.post('/expressions', (req, res, next) => {
  const receivedExpression = createElement('expressions', req.query);
  if (receivedExpression) { // <-- here
    expressions.push(receivedExpression);
    res.status(201).send(receivedExpression);
  } else {
    res.status(400).send();
  }
});

So if the value returned by the createElement('expressions', req.query) is false then the API call will result in HTTP code 400 which means “bad request” and indicates that something was wrong with the request we made.


So, request /expressions?not_emoji=%F0%9F%98%8D&not_name=Heart%20eyes will result in error 400. But your question is a little broader:

How does the function know that req.query contains the correct parameters for name and emoji?

The answer is - it doesn’t. It just checks if emoji and name are present in the parameters, but it does not validate emoji property to see if it actually is an emoji.

That’s why request /expressions?emoji=not%20a%20real%20emoji&name=Emoji,%20trust%20me will result in HTTP code 200 (OK) and this output:

{
  "id": 5,
  "emoji": "not a real emoji",
  "name": "Emoji, trust me"
}

I hope that answers your question. If you would like to - you can always add validation that makes sure that emoji property is, in fact, an emoji :wink:

18 Likes

That really helped clear that up, thank you :grin:

1 Like

I feel better seeing this and understanding the lessons, instead of see the solutions.

2 Likes

In the exercise it says to test your route, use the POST tab in the upper left corner. Select a name and emoji and send the request to see if your route works as intended.
But I can’t see any tab(POST),
can somebody help please.

They mean the create-tab. It doesn’t say PUT, it says create.

Have you started the expressions-machine in bash?

In the black screen where the tab says ‘bash’, you type node app.js
Then you get a reply that says Listening on port 4001

Once you have that, you go the white screen that says http://localhost:4001 and click the refresh button. Then you will get the expressions-machine with the tabs you’re looking for.

2 Likes

Why do you need to put .send() after a
res.status(400); ?

since you are not sending anything else back?

this kept me from passing this exercise for quit some time :sweat_smile: (without any hint what was wrong from the test)

after some searching i found that
res.sendStatus(400) also passes the test

we can post a new expression without writing anything in the name field. how can we fix that?

Edit:
I figured it out myself . in the if statement we can make sure the .name property is not an empty string

if(newExpression && newExpression.name !== ‘’)

Lesson after lesson in this section I become increasingly exasperated because it’s the same issues in each one. It’s not remotely clear what is actually being asked to do, especially within the scope of the actual new material. This lesson the only thing having to do with the new material is knowing to use “app.post” instead of .get or .push or anything. The main bulk of what you’re actually expected to do comes from understanding the createElement function. Not a great way to cement what you’re learning when the exercise is actually about something else.

My suggestion is to completely redo this Express material. It’s awful, it’s garbage, it’s the worst part of codecademy I’ve experienced thusfar due to vagueness and poor instructions. The only way I’ve been able to get through is immediately looking at the solution and copying (since the built in copy button is broken and even looking at the help page at all breaks the browser) and as soon as I look at the solution code I feel no shame in doing so because there’s no way I would have gotten there on my own due to awful instructions. I’ll be learning Express elsewhere since the amount of good these lessons have done me beyond knowing the app.* functions is NONE

23 Likes

Anyone else passing the lesson but getting a 400 Bad Request when trying to create a new expression using “Create”.

This is in relation to step 12/15, after implementing the app.post().

I looked at the solution and it seems to me that we’re the same, but getting the error upon testing.

// Add your POST handler below:
app.post('/expressions', (req, res, next) => {
  const newExpression = createElement('expressions', req.query);
  if (newExpression) {
    expressions.push(newExpression);
    res.status(201).send(newExpression);
  } else {
    res.status(400).send('Invalid');
  }
});

From the instructions:

Don’t forget to restart your server and test as you implement the functionality. To test your route, use the POST tab in the upper left corner. Select a name and emoji and send the request to see if your route works as intended.

I really dislike learning Express through helper ./utils functions — I’m learning something custom, not Express itself.
In the final solution, I didn’t have the ID counter so that it wouldn’t repeat and there was the next ordinal number, so I had to invent myself.

app.post('/expressions/', (req, res, next) => {
  const newItem = createElement(expressions, req.query); // does not help at all in learning 
  newItem['id'] = expressions.length + 1; // no way without it, up: if items were removed from the middle, then it’s not a very good solution
  console.log(newItem);
  if (newItem) {
    expressions.push(newItem);
    res.status(201).send(newItem)
  } else {
    res.status(400).send('Oh no')
  }
})

I am not satisfied with the quality of the material in the PRO course :angry:

5 Likes
app.post("/expressions", (req, res, next) => {
  if (req.query.emoji && req.query.name) {
    const newEl = createElement("expressions", req.query);
    expressions.push(newEl);
    return res.status(201).send(newEl);
  } else {
    res.status(400).send("");
  }
});

As I didn’t read the createElement helper function when doing this, I interpreted the instruction to check “it is a valid new expression (meaning it has an emoji and name key)” a bit differently, by just checking those keys exist. It seems to work and I find it a bit easier to understand than the solution code.