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 trialBrian Patterson
19,588 PointsGetting a 404 when I click the answer link.
I have tried to follow along and this is the code I have written.
const express = require('express');
const router = express.Router();
const { data } = require('../data/flashcardData.json');
//the above is the same as:
//const data = require('../data/flashcardData.json').data;
const { cards } = data;
router.get('/:id', (req, res) => {
// Here, we're setting either the string "answer" or the string "question" to a variable called side
const side = req.query.side; // "answer"
// Here, we're setting the index of the client's desired "card" to a variable called id
const id = req.params.id; // 1232
// This step has two parts: we're getting the specific "card" from the "cards" array using the id variable as an index number
// Then, once we have a "card" object, we're grabbing the string of text inside of its "answer" property and assigning it to the variable "text"
// We get the string of text inside of "answer" — instead of "question" — because that's what the value of "side" above happens to be
const text = cards[id][side];
// Similarily, "hint" will contain the the string of text inside of the "hint" property of the the selected "card" object
const hint = cards[id];
// This step is really for readability and is arguably unnecessary
// Basically, you're setting "templateData" with {text: "Something, something, answer", hint: "hint for the question"}
const templateData = { id, text };
// Finally, we build our card.pug template using the contents of templateData, and send the resulting HTML to the client
//get answer from question.
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;
This is in my card.pug file.
extends layout.pug
block content
section#content
h2= text
//h3= answer
if hint
p
i Hint: #{hint}
a(href=`${id}?side=${sideToShow}`)= sideToShowDisplay
So why am I getting a 404?
Brian Patterson
19,588 PointsHere is my 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((req, res, next) => {
const err = new Error('Not Found');
err.status = 404;
next(err);
});
app.use((err, req, res, next) => {
res.locals.error = err;
const status = err.status || 500;
res.status(status);
res.render('error');
});
app.listen(3000, () => {
console.log('The application is running on localhost:3000!');
});
Brian Patterson
19,588 PointsThe problem seems to be the link. I have pretty much copied his code word for word and it still does not work.
http://localhost:3000/cards/4/4?side=answer
As you can see it is wrong it repeats the id. Dare I assume that his code is WRONG!
2 Answers
Brian Anstett
5,831 PointsHey Brian, so currently the way you have it set up, you want to go to localhost://cards/{id}?side={something}, not localhost://{id}?side={something}. I'm not exactly sure what functionality is supposed to happen when you click on that link but just recall how "routes" work with express. With the route 'localhost://cards/4?side=answer', the following line in your app.js file matches the first part of the path, the "/cards".
app.use('/cards', cardRoutes);
//matches any route that starts with /cards
//localhost://cards/helloworld : matches
//localhost://cards/about :matches
//localhost://cards/****** :matches
//localhost://4?side=answer :does not match
Now that we matched all routes that start with '/cards', we tell our app to go check out 'cardRoutes' (./routes/cards) to match our path (url) with anything that comes after /cards.
so in our routes/cards.js
router.get('/:id', (req, res) => {}
//localhost://cards/4 :matches with req.prarms.id= 4 and req.query.side== null/undefined
//localhost://cards/4?side=answer :matches with req.prarms.id= 4 and req.query.side == 'answer'
//localhost://cards/about :matches with req.params.id == about and req.query.side == null/undefined
So in short, you just need to change your link in cards.pug to point to /cards/{id}?side={something here}
Brian Patterson
19,588 Pointshow do I do that? This matches what he has in the tutorial.
Brian Patterson
19,588 PointsThanks Brian Anstett. Still trying to get my head around this. I changed the pug file to the following.
a(href=`/cards/${id}?side=${sideToShow}`)= sideToShowDisplay
That seemed to work. Although, I am confused as to why it duplicated the id.
Brian Anstett
5,831 PointsI'm not sure why there's a double id either, I didn't watch the video. If you wanted a second id parameter in your route, you could just add the following in routes/cards.js.
router.get('/:id/:id2', (req, res, next)=>{})
//localhost://cards/4/5 :matches with req.params.id==4 and req.params.id2=5
Brian Anstett
5,831 PointsBrian Anstett
5,831 PointsHey Brian Patterson, can you post your app.js? Because you have taken advantage of the express.router() module in a separate file you need to make sure your application has a way to get to those routes either with a line like...
Another suggestion I would have is change your link (a tag) in your card.pug file to an absolute link opposed to relative. Recall that relative paths are from your current location. This can cause problems if you're on a different page already.
a(href=`/${id}?side=${sideToShow}`)= sideToShowDisplay