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

Charlie Roberts
Charlie Roberts
12,014 Points

http://localhost:3000/cards not loading but I can see the sides of the cards. Not sure where I went wrong?

I can get see the sides of the cards here: http://localhost:3000/cards/3?side=answer

But I get an error when I view cards here: http://localhost:3000/cards

index.js

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

//get method is used to handle the Get requests to a certain url
//this callback will run when the client requests this route
router.get('/',(req, res) => {    //location parameter, anonymous callback function
    const name = req.cookies.username;
    if (name) {
        res.render('index', { name }); //The response object's `render` method takes the name of a template as its first parameter
    } else {
        res.redirect('/hello');
    }
}); 

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) //this will send a cookie to the crowser after we submit the form
    res.redirect('/'); 
}); 

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

module.exports = router;

index.pug

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

//get method is used to handle the Get requests to a certain url
//this callback will run when the client requests this route
router.get('/',(req, res) => {    //location parameter, anonymous callback function
    const name = req.cookies.username;
    if (name) {
        res.render('index', { name }); //The response object's `render` method takes the name of a template as its first parameter
    } else {
        res.redirect('/hello');
    }
}); 

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) //this will send a cookie to the crowser after we submit the form
    res.redirect('/'); 
}); 

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

module.exports = router;

cards.js

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

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

//pass in an object{}, passing the property prompt 
router.get('/:id', (req, res) => { 
    const { side } = req.query;
    const { id } = req.params;

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

    const text = cards[id][side];
    const { hint } = cards[id];

    const templateData = { id, text };

    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;

app.js

//require Express module and assign to a variable
const express = require('express');
const cookieParser = require('cookie-parser');

// create Express application and assign it to a variable
const app = express();

app.use(express.urlencoded()); // middleware for parsing http payloads
app.use(cookieParser());

//tell Express to use Pug Template Engine
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;
    res.status(err.status);
    res.render('error', err);
    next();
});

//setup development server
app.listen(3000, () => {
    console.log('The application is running on localhost:3000')
});
Charlie Roberts
Charlie Roberts
12,014 Points

I get this error when I visit http://localhost:3000/cards: RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: undefined at ServerResponse.writeHead (node:http_server:352:11) at ServerResponse._implicitHeader (node:_http_server:338:8) at write (node:http_outgoing:963:9) at ServerResponse.end (node:_http_outgoing:1080:5) at ServerResponse.send (/Users/charlie/flashcards/node_modules/express/lib/response.js:232:10) at done (/Users/charlie/flashcards/node_modules/express/lib/response.js:1035:10) at exports.renderFile (/Users/charlie/flashcards/node_modules/pug/lib/index.js:448:12) at exports._express as engine at View.render (/Users/charlie/flashcards/node_modules/express/lib/view.js:135:8) at tryRender (/Users/charlie/flashcards/node_modules/express/lib/application.js:657:10)

Jamie Reardon
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Jamie Reardon
Treehouse Project Reviewer

Hi @Charlie Roberts most of the time these follow along issues are related to typo's in the code when copying. It can also come down to a package version difference when it also specifically is related to node. Please confirm that you have double checked for any typo's etc as well as the package versions for each package the app is using is the same as the course.

Tip: You can quickly check for code differences using diffchecker

Charlie Roberts
Charlie Roberts
12,014 Points

I've gone over the code a couple times with the video and re written it, if it's a typo I can't find it. I'm was using the current version of node(21.2.0) but the video was using an older version - I didn't think it would cause an error.

Jamie Reardon
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Jamie Reardon
Treehouse Project Reviewer

@Charlie Roberts if you have checked files you have manually created yourself (rather than using the original source code from the videos) using diffchecker (which makes it easy to find differences as you don't have to manually check with your own eyes) and its the same, then you can safely rule that out. Since there is a difference for node, I would suggest trying to use the same version as well as the package versions, APIs do change and can cause conflicts which results in errors.

1 Answer

Simon Coates
Simon Coates
8,377 Points

If you're working in a workspace, then you could post a snapshot. People can then debug a copy of your code. You can generate that error message by directly setting your status code to undefined. So that output you highlighted before seems to be your error handler running. You might be able to get at the real error if you update the the res.status call to

res.status(err.status || 500)

The only part of your code that seems to call status is the error handler. As long as it's only dealing with errors you create, the err object should always have a status. If something else throws an error, your error handler might be running without err being populated as expected. So there's a scenario in which 2 errors are occurring, but the second obscures the first.