X-Press Publishing TypeError: Cannot read property 'artist' of undefined

Hello,

I´m working from the X-Press Publishing project. And I got struggled. It seems like my post can access to my database. I´ve double-checked my code but not error is found.

If someone could help I will be very glad.

Thank you


api.js

const express = require('express');

const apiRouter  = express.Router();
const artistsRouter = require('./artist.js');
const seriesRouter = require('./series.js');

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




module.exports = apiRouter;

migration.js

const sqlite3= require('sqlite3');
const db = new sqlite3.Database('./database.sqlite');

db.serialize(function(){
    db.run('CREATE TABLE IF NOT EXISTS `Artist` ( ' +
    '`id` INTEGER NOT NULL, ' +
    '`name` TEXT NOT NULL, ' +
    '`date_of_birth` TEXT NOT NULL, ' +
    '`biography` TEXT NOT NULL, ' +
    '`is_currently_employed` INTEGER NOT NULL DEFAULT 1, ' +
    'PRIMARY KEY(`id`) )')

    db.run('CREATE TABLE IF NOT EXISTS `Series` ( ' +
    '`id` INTEGER NOT NULL, ' +
    '`name` TEXT NOT NULL, ' +
    '`description` TEXT NOT NULL, '  +
    'PRIMARY KEY(`id`) )')
})

server.js

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

const app = express();
const PORT = process.env.PORT || 4000;

const apiRouter = require('./API/api');
const errorHandler = require('errorhandler');
app.use('/api', apiRouter);


app.use(errorhandler());

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


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

module.exports = app

artist.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)=>{
    const sql = 'SELECT * FROM Artist WHERE Artist.id = $artistId';
    const values = {$artistId: artistId};
    db.get(sql, values, (error, artist) => {
        if(error){
            next(error);
        } else if (artist){
           req.artist = artist;
           next();
        } else{
            res.sendStatus(404);
        }
});
})

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

artistsRouter.get('/:artistId', (req, res, next) =>{
    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.isCurrentlyEmployed===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 id = ${this.lastId}`,(error , artist) =>{
                res.status(201).send(json({artist : artist}));
            })
        }
    });
})
module.exports = artistsRouter;

Try using this.lastID instead. If the code got to this point, then your SELECT statement should be returning a result

Thanks for your help, but it doesn´t solve the error.

The other thing I notice in your POST route is this:

You didn’t chain json(). Try either of these:

      res.status(201).json({artist: artist}); 
                  // or
      res.status(201).send({artist: artist});

Thanks again, other error I didn´t notice but I´m still having the same error.

Ah, this seems to be an interesting problem that demonstrates the importance of the order in express middleware. The error messages from the tests didn’t make it obvious.

If you look at your code above, you can see that you’re setting up your /api route before using the other middleware, such as the json body-parser, etc. So the functionality that the middleware provides isn’t available to you. (You also have a small typo in your use of errorHandler())

Check out this order:

const errorHandler = require('errorhandler');
app.use(errorHandler());

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

const apiRouter = require('./API/api');
app.use('/api', apiRouter);

Now the functionality of the express middleware packages should be available in your API routes

1 Like

Thank you so much. You are such a nice user. You´ve just solved my headache.
Now it´s running perfectly.

1 Like

Thanks very much, I had the same problem and this fixed it.

I think the reason I originally placed the middleware in the wrong order was because in the artistRouter section, we’re meant to pass errors to the errorHandler using next(error).

So my assumption was that the errorHandler and other middleware should therefore come after the api, otherwise the error wouldn’t be passed on correctly?

If anyone could explain how that bit works, that would be really helpful!