Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Express Basics Parameters, Query Strings, and Modularizing Routes Linking Around the Application

The Next card link

Hi. I clicked on the Next card link but the page won't work and localhost isn't sending any data.

app.js:

const express = require("express");
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");

const app = express();

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

app.set("view engine", "pug");

const mainRoutes = require("./routes");
const cardRoutes = require("./routes/cards");

app.use(mainRoutes);
app.use("/cards", cardRoutes);

app.use((err, req, res, next) => {
  res.locals.error = err;
  res.status(err.status);
  res.render("error", err);
});

app.listen(3000, () => {
  console.log("The application is running on localhost:3000!");
});

index.pug:

extends layout.pug

block content
  section#content
    p
      a(href="/cards") Begin!

card.pug:

extends layout.pug

block content
  section#content
    h2= text
    if hint
      p
        i Hint: #{hint}
    a(href=`${id}?side=${sideToShow}`)= sideToShowDisplay
    br
    a(href="/cards") Next card

layout.pug:

doctype html
html(lang="en")
  head
    title Flash Cards
  body
    include includes/header.pug
    if name
      h2 Welcome, #{name}!
      form(action="/goodbye", method="post")
        button(type="submit") Goodbye
    block content
    include includes/footer.pug

goodbye.pug:

extends layout

block content
  form(action="/goodbye", method="post")
    button Goodbye!

error.pug:

extends layout

block content
  h1= error.message
  h2= error.status
  pre= error.stack

I would appreciate any help please.

32 Answers

ooo wait!

router.get("/:id", (req, res) => {
  const {side} = req.query;
  const {id} = req.params;

  if (!side) {
    res.redirect("/cards/${id}?side=question");
  }

you are trying to access the value of id in the redirect, but you aren't using a template literal. could that be it?

ok think i found the problem:

router.get("/:id", (req, res) => {
  const {side} = req.query;
  const {id} = req.params;

  if (!side) {
    res.redirect("/cards/${id}?side=question");
  }

in your route handler here you are setting const {id} to req.params. this should be set to req.params.id

let me know if that works!

Hi Sean! can we see the routes file?

Hi Natalie.

My index.js:

const express = require("express");
const router = express.Router();

router.get("/", (req, res) => {
  const name = req.cookies.username;
  if (name) {
    res.render("index", {name});
  } else {
    res.redirect("/hello");
  }
  res.render("index", {name: name});
});

router.get("/hello", (req, res) => {
  const name = req.cookies.username;
  if (name) {
    res.redirect("/");
  } else {
    res.render("hello");
  }
});

router.post("/hello", (req, res) => {
  res.cookie("username", req.body.username);
  res.redirect("/");
});

router.post("/goodbye", (req, res) => {
  res.clearCookie("username");
  res.redirect("/hello");
});

//router.use((req, res, next) => {
//  const err = new Error("Not Found");
//  err.status = 404;
//  next(err);
//});

module.exports = router;

cards.js:

const express = require("express");
const router = express.Router();
const {data} = require("../data/flashcardData.json");
const {cards} = data;

router.get("/", (req, res) => {
  const numberOfCards = cards.length;
  const flashcardId = Math.floor(Math.random() * numberOfCards);
  res.redirect(`/cards/${flashcardId}`);
});

router.get("/:id", (req, res) => {
  const {side} = req.query;
  const {id} = req.params;

  if (!side) {
    res.redirect("/cards/${id}?side=question");
  }

  const name = req.cookies.username;
  const text = cards[id][side];
  const {hint} = cards[id];

  const templateData = {id, text, name};

  if (side === "question") {
    templateData.hint = hint;
    templateData.sideToShow = "answer";
    templateData.sideToShowDisplay = "Answer";
  } else if (side === "answer") {
    templateData.sideToShow = "question";
    templateData.sideToShowDisplay = "Question";
  }

  res.render("card", templateData);
});

module.exports = router;

so to render the next card the link route should be /cards/:id, but your link in the pug file is only to /cards

are there any errors in your terminal?

Hi Natalie. Thanks for your help so far.

I added .id to the end of that line.

It's still not working. The error message in my terminal is:

RangeError: Invalid status code: undefined

hey Sean! sorry I disappeared! (Easter and all) what url are you using to access the page? also, in the same route I mentioned earlier, I think you might have to use req.query.side, not just req.query

Hello Sean. Natalie find your problem. The wrong in the cards.js section of res.redirect(/cards/${flashcardId}?side=question). You lost the query string. Have a nice day!

Hi Natalie and Adam. Thank you both for replying. I took Easter off as well so no problem. And Natalie, I appreciate your help.

I'm very sorry but it's still not working. Is this what you were talking about?

router.get("/", (req, res) => {
  const numberOfCards = cards.length;
  const flashcardId = Math.floor(Math.random() * numberOfCards);
  res.redirect(`/cards/${flashcardId}?side=question`);
});

I typed in the URL http://localhost:3000/cards/ and http://localhost:3000/cards/3?side=question.

The message I got was:

Flash Cards
Not Found
404
Error: Not Found
    at router.use (C:\Users\user\Desktop\treehouse\routes\index.js:34:15)
    at Layer.handle [as handle_request] (C:\Users\user\Desktop\treehouse\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\user\Desktop\treehouse\node_modules\express\lib\router\index.js:317:13)
    at C:\Users\user\Desktop\treehouse\node_modules\express\lib\router\index.js:284:7
    at Function.process_params (C:\Users\user\Desktop\treehouse\node_modules\express\lib\router\index.js:335:12)
    at next (C:\Users\user\Desktop\treehouse\node_modules\express\lib\router\index.js:275:10)
    at Function.handle (C:\Users\user\Desktop\treehouse\node_modules\express\lib\router\index.js:174:3)
    at router (C:\Users\user\Desktop\treehouse\node_modules\express\lib\router\index.js:47:12)
    at Layer.handle [as handle_request] (C:\Users\user\Desktop\treehouse\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\user\Desktop\treehouse\node_modules\express\lib\router\index.js:317:13)
An app to help you study

Nothing came up in the command prompt.

I looked at my index.js file and found this:

router.use((req, res, next) => {
  const err = new Error("Not Found");
  err.status = 404;
  next(err);
});

try putting that error block in app.js just above your general error handler

In index.js please cut the last router.use((req, res, next) function and past into app.js file from the bottom to the third place.

I've put the router.use block in the app.js file, third from the bottom. The block immediately below that is

app.use((err, req, res, next) => {
  res.locals.error = err;
  res.status(err.status);
  res.render("error", err);
});

Immediately above the router.use block:

app.use(mainRoutes);
app.use("/cards", cardRoutes);

I don't understand but i uploaded my solution on github. https://github.com/trAApex/mysolution

Sorry Adam, a typo on my part. I've edited my last post. Thank you.

So your code is run? I will not give up. I will find the error in code.

Hi @adambeer. It's still not running. In the prompt, the error message:

ReferenceError: router is not defined
at app.js:19:1

Now here's the line in question:

router.use((req, res, next) => { // <== This line
  const err = new Error("Not Found");
  err.status = 404;
  next(err);
});

I'm looking at your code now and comparing it with mine. I've noticed some differences between our respective app.js files.

Here's mine:

const express = require("express");
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");

const app = express();

app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static("public"));

app.set("view engine", "pug");

const mainRoutes = require("./routes");
const cardRoutes = require("./routes/cards");

app.use(mainRoutes);
app.use("/cards", cardRoutes);

router.use((req, res, next) => {
  const err = new Error("Not Found");
  err.status = 404;
  next(err);
});

app.use((err, req, res, next) => {
  res.locals.error = err;
  res.status(err.status);
  res.render("error", err);
});

app.listen(3000, () => {
  console.log("The application is running on localhost:3000!");
});

And yours:

const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');

const app = express();

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

// tells express which template engine to use
app.set('view engine', 'pug');
app.use('/static', express.static('public'));

const mainRoutes = require('./routes');
const cardRoutes = require('./routes/cards');

app.use(mainRoutes);
app.use('/cards', cardRoutes);

app.use((req, res, next) => {
    const err = new Error('Not Found');
    err.status = 404;
    next(err);
});

app.use((err, req, res, next) => {
    res.locals.error = err;
    res.status(err.status);
    res.render('error', err);
});

app.listen(3000, () => {
    console.log('The application is running on localhost:3000');
});

Your solution, is it the final product? Have you finished this course? I only ask because I haven't.

Yes, I've finished course. This is the final product.

Please fix the router.use function to app.use

Adam Beer Done.

RangeError: Invalid status code: undefined

You do not need the goodbye.pug file. You copied it into the layout.pug file. And delete your eleventh rows in app.js. Unnecessary the res.render("index", {name: name}); . I can't see anything else difference. I used ' ' and not " " but this isnt problem. And now don't work?

Hi Adam. Thanks for your help. I've deleted the goodbye.pug file and the res.render line. Still the same error as before.

Hi Sean! Please upload your project files to github. I check it.

I don't know how.

Search your folder with git bash.You get in. In your folder use git init command, after use git add command and add your folders one by one without node_modules folder. After git commit -m "Your message". And now make new repository in github and copy the link. Now in git bash use gut remote add origin (+ your repository url), after git push -u origin master. And then you uploaded yours files to gitfub. And please share your link.

Hi. I've opened the git bash. I added the folder I'm using. I can't add the files inside it.

Here's the link:

https://github.com/SeanFl42/Treehouse-Express-Basics.git

Guil Hernandez
STAFF
Guil Hernandez
Treehouse Teacher

Hi Sean Flanagan!

It looks like the GitHub repository you linked to is empty. Could you please update it with the latest files so I can have a look and help out? :)

Hi Guil.

I've tried updating the repository but I don't know how to.

I typed in

git add app.js

and I got

fatal: Unable to create 'C:/Users/user/.git/index.lock': File exists.

Another git process seems to be running in this repository, e.g.
an editor opened by 'git commit'. Please make sure all processes
are terminated then try again. If it still fails, a git process
may have crashed in this repository earlier:
remove the file manually to continue.

Hi Sean. Please use git log. What does it happened?

Guil Hernandez
STAFF
Guil Hernandez
Treehouse Teacher

Sean Flanagan,

Deleting index.lock usually solves this issue. Check out this post. You could also zip up your files and email them to me at guil@teamtreehouse in the meantime.

I tried

git log app.js

Output:

fatal: your current branch 'Stage4Video1' does not have any commits yet

Stage4Video1 is Stage 4 Video 1 of the Gulp Basics course:

https://teamtreehouse.com/library/putting-multiple-tasks-together

Guil Hernandez
STAFF
Guil Hernandez
Treehouse Teacher

Hey Sean Flanagan,

I think your issue is here:

if (!side) {
  res.redirect("/cards/${id}?side=question");
}

The path inside res.redirect() should be a template literal. Try replacing the double quotes with backticks. Let me know if that works for you. :)

if (!side) {
  res.redirect(`/cards/${id}?side=question`);
}

Hi Guil.

Output:

RangeError: Invalid status code: Undefined
Guil Hernandez
STAFF
Guil Hernandez
Treehouse Teacher

Thanks for posting the output. To get past the error, try this modification to your error route handler in app.js:

app.use((err, req, res, next) => {
  res.locals.error = err;
    if (err.status) {
      res.status(err.status);
    }
    res.render('error', err);
});

That could help prevent that RangeError when the status code is undefined. Let me know what the output is after that.

Hi Guil.

I typed in the URL http://localhost:3000/cards/undefined?side=question and got a very long series of error messages in the command prompt.

Error: can't set headers after they are sent.

Hi Sean! Check this link. How do you make new repo and upload your files to GitHub. It is just few minutes. https://www.youtube.com/watch?v=9RqXo6VD-jw