X-Press Publishing - Step 35: Passing test, but 404 on localhost

Hello,

So I’ve been going through this project today, I’d just finished up with the Artist section and was instructed to start the server up on local host. Despite passing all the tests, when trying to load up the server I get a GET / 404 error. I’ve looked through the routes and double checked it with the tutorial video and solution code and can’t see what could be wrong. Anyone have any ideas?

Here are my js files:
server.js:

const express = require('express');
const app = express();
const PORT = process.env.PORT || 4001;

const bodyParser = require('body-parser');
const morgan = require('morgan');
const cors = require('cors');
const errorHandler = require('errorhandler');

const apiRouter = require('./api/api');

app.use(bodyParser.json());
app.use(morgan('dev'));
app.use(cors());

app.use('/api', apiRouter);

app.use(errorHandler());

app.listen(PORT, () => {
    console.log(`Server is listening on PORT ${PORT}`);
})

module.exports = app;

api.js:

const express = require('express');
const apiRouter = express.Router();
const artistsRouter = require('./artists.js');

apiRouter.use('/artists', artistsRouter);

module.exports = apiRouter;

artists.js

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

const sqlite3 = require('sqlite3');
const db = new sqlite3.Database(process.env.TEST_DATABASE || './database.sqlite');

artistsRouter.param('artistId', (req, res, next, artistId) => {
    db.get("SELECT * FROM Artist WHERE Artist.id = $artistId",
    {
        $artistId: artistId
    },
    (err, artist) =>{
        if (err) {
            next(err);
        } 
        else if (artist) {
            req.artist = artist;
            next();
        }
        else {
            res.sendStatus(404);
        }
    });    
});

artistsRouter.get('/', (req, res, next) => {
    db.all("SELECT * FROM Artist WHERE Artist.is_currently_employed = 1;", (err, artists) => {
        if (err) {
            next(err);
        } else {
            res.status(200).json({ artists: artists })
        } 
        
    });
});


artistsRouter.get('/:artistId', (req, res, next) => {
    return res.status(200).json({ artist: req.artist });
})

artistsRouter.post('/', (req, res, next) => {
   const name = req.body.artist.name;
   const dateOfBirth = req.body.artist.dateOfBirth;
   const biography = req.body.artist.biography;
   const isCurrentlyEmployed = req.body.artist.is_currently_employed === 0 ? 0 : 1;
   if (!name || !dateOfBirth || !biography) {
      return res.sendStatus(400);
   }

   const sql = "INSERT INTO Artist (name, date_of_birth, biography, is_currently_employed) VALUES ($name, $dateOfBirth, $biography, $isCurrentlyEmployed);"
   const values = {
        $name: name,
        $dateOfBirth: dateOfBirth,
        $biography: biography,
        $isCurrentlyEmployed: isCurrentlyEmployed
    }
   db.run(sql, values, function(error) {
       if (error) {
            next(error);
       } else {
        db.get(`SELECT * FROM Artist WHERE Artist.id = ${this.lastID};`, 
        (error, artist) => {
            return res.status(201).json({ artist: artist });
       })
    }
   })
});

artistsRouter.put('/:artistId', (req, res, next) => {
    const name = req.body.artist.name;
    const dateOfBirth = req.body.artist.dateOfBirth;
    const biography = req.body.artist.biography;
    const isCurrentlyEmployed = req.body.artist.is_currently_employed === 0 ? 0 : 1;
    if (!name || !dateOfBirth || !biography) {
       return res.sendStatus(400);
    }
    const sql = 'UPDATE Artist SET name = $name, date_of_birth = $dateOfBirth, biography = $biography, ' +
                'is_currently_employed = $isCurrentlyEmployed WHERE Artist.id = $artistId';
    const values = {
        $name: name,
        $dateOfBirth: dateOfBirth,
        $biography: biography,
        $isCurrentlyEmployed: isCurrentlyEmployed,
        $artistId: req.params.artistId
    };
    db.run(sql, values, function(error) {
        if (error) {
            next(error);
        } else {
            db.get(`SELECT * FROM Artist WHERE Artist.id = ${req.params.artistId};`, 
            (error, artist) => {
                return res.status(200).json({ artist: artist });
           })
        }
    })
});

artistsRouter.delete('/:artistId', (req, res, next) => {
    const sql = `UPDATE Artist SET is_currently_employed = 0 WHERE Artist.id = $artistId`;
    const value = {
        $artistId: req.params.artistId
    };
    db.run(sql, value, (error) => {
        if (error) {
            next(error);
        } else {
            db.get(`SELECT * FROM Artist WHERE Artist.id = ${req.params.artistId}`,
            (error, artist) => {
                return res.status(200).json({ artist: artist })
            })
        }
    })

})


module.exports = artistsRouter;

Apologies for the large chunk of code, been stumped on this for hours!
Project Link: https://www.codecademy.com/paths/web-development/tracks/building-a-persistent-api/modules/persistent-api-cumulative-projects/projects/x-press-publishing

Hello, and welcome to the forums.

You can open up the index.html file directly in your browser without it going through localhost. As long as your back-end is running, your front-end (the index.html file) will be able to make the API calls to it.

There aren’t any rules in server.js to serve the static files of the front-end right now. It’s possible to add a / and /public route to serve them if you’d like for testing, but it isn’t covered in the project steps and it isn’t required to view the front-end.

1 Like

Hi, thank you for the response!

Yes I had a go opening the index.html directly but it doesn’t seem to be working with the backend (the functionality doesn’t work)? In the help video at this step his terminal comes up with ‘GET /api/artists 200’ after opening index and starting server.js, whereas mine is just ‘GET / 404’. Would this suggest I’ve made a mistake somewhere?

The message GET / 404 sounds like you’re still trying to access the front-end through the localhost rather than opening up the file directly in your browser.

The reason that your front-end isn’t able to communicate with your back-end is that you’re running your server on port 4001 instead of 4000. The front-end that Codecademy supplies for this project is hardcoded to access the APIs through port 4000. If you wanted to change that, you’d need to alter the code in /src/utils/XPress.js and re-run webpack to produce the bundled files again.

Assuming you didn’t tell Express to listen on 4001 on purpose because something else was using 4000, it would be much easier to change the port your server uses to 4000. That should allow your front-end to communicate with the back-end

1 Like

That makes a lot more sense, I hadn’t realised the port number was specifically tied in with the front-end. Thanks for all your help I really appreciate it. :slight_smile: