3therk1ll
3therk1ll

Reputation: 2441

'id' not defined when referencing JSON object in NodeJs endpoint

I am new to Javascript and have been following along with a course on NodeJs and am stuck on an exercise.

I am creating a basic CRUD API for 'genres' in a made up video store.

I have created all of the above but when I call any of the endpoint with a specific id I get an error.

TypeError: Cannot read property 'id' of undefined
    at genres.find.g (/Users/richardcurteis/Desktop/NodeJsCourse/vidly-node/index.js:60:65)
    at Array.find (native)
    at findGenre (/Users/richardcurteis/Desktop/NodeJsCourse/vidly-node/index.js:60:26)

The issue is (I think) related to the findGenre method which checks to see if a genre with the matching id exists.

function findGenre(req) {
    const genre = genres.find(g => g.id === parseInt(req.params.id));
    if(genre) return genre;
    false;
}

The json object is currently hardcoded.

This is the request (sent from Postman):

GET > http://localhost:5000/api/genres/1

This returns:

[
    {
        "id": 1,
        "name": "Action"
    },
    {
        "id": 2,
        "name": "Horror"
    },
    {
        "id": 3,
        "name": "Drama"
    }
]

I have checked against the solution and it appears to be the same implementation as mine, save for my refactoring repetitive checks and error codes.

Maybe I'm just going code blind, but maybe someone can see what I'm missing?

I have included the entire class (?) but like I said the error is related to the checking of the json objects id.

const Joi = require('joi');
const express = require('express');
const app = express();

app.use(express.json());

const genres = [
    { id: 1, name: 'Action' },
    { id: 2, name: 'Horror' },
    { id: 3, name: 'Drama' },
];

app.get('/api/genres', (req, res) => {
    res.send(genres);
});

app.post('/api/genres', (req, res) => {
    const { error } = validateGenreName(req.body);
    if(error) return sendValidationError(res, error);

    const genre = {
        id: genres.length + 1,
        name: req.body.name
    };
    genres.push(genre);
    res.send(genre);
});

app.put('/api/genres/:id', (res, req) => {
    const genre = findGenre(req);
    if(!genre) return genreNotFoundError(res);

    const { error } = validateGenreName(req.body);
    if(error) return sendValidationError(res, error);

    genre.name = req.body.name;
    res.send(genre);
});

app.delete('/api/genres/:id', (res, req) => {
    const genre = findGenre(req);
    if(!genre) genreNotFoundError(res);

    const index = genres.indexOf(genre);
    genres.splice(index, 1);

    res.send(genre);
});

app.get('/api/genres/:id', (res, req) => {
    const genre = findGenre(req);
    if(!genre) return genreNotFoundError(res);
    res.send(genre);
});


// Functions

function findGenre(req) {
    const genre = genres.find(g => g.id === parseInt(req.params.id));
    if(genre) return genre;
    false;
}

function genreNotFoundError(res) {
    res.status(404).send('Genre not found');
}

function validateGenreName(genre) {
    const schema = {
        name: Joi.string().min(3).required()
    };
    return Joi.validate(genre, schema);
}

function sendValidationError(res, error) {
    res.status(400).send(error.details[0].message);
}

const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Listening on port ${port}`));

Upvotes: 3

Views: 744

Answers (1)

ralphtheninja
ralphtheninja

Reputation: 133118

Now I see your problem. You have flipped (req, res) for the .get handler.

app.get('/api/genres/:id', (res, req) => {
    const genre = findGenre(req);
    if(!genre) return genreNotFoundError(res);
    res.send(genre);
});

Should be

app.get('/api/genres/:id', (req, res) => {
    const genre = findGenre(req);
    if(!genre) return genreNotFoundError(res);
    res.send(genre);
});

The same goes for .delete and .put.

Upvotes: 2

Related Questions