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 Build a REST API With Express Completing and Testing the API Test Routes with Postman

Mary Paul
Mary Paul
13,792 Points

Getting a 500 error with questions/:id/answer route

In Postman, GET /questions works, POST /questions works, GET /question/(demoQuestionID) gives me a 200 (although I don't see the question text anywhere,) but /questions/(demoQuestionID)/answers gives me a 500 error. Thoughts?

app.js

'use strict';

var express = require("express");
var app = express();
var routes = require("./routes");

var jsonParser = require("body-parser").json;
var logger = require("morgan");

app.use(logger("dev"));
app.use(jsonParser());

var mongoose = require("mongoose");

mongoose.connect("mongodb://localhost:27017/sandbox");

var db = mongoose.connection;

db.on("error", function(){
    console.log("There were problems", err);
});

db.once("open", function(){
    console.log("looks like db connection works bro");
});


app.use("/questions", routes);

// catch 404 errors
app.use(function(req, res, next){
    var err = new Error("Page Not Found");
    err.status = 404;
    next(err);
});

//Error handler
app.use(function(err, req, res, next){
    res.status(err.status || 500);
    res.json({
        error: {
            message: err.message
        }
    });
});


var port = process.env.PORT || 3000;

app.listen(port, function(){
    console.log("Express server listening on port", port);
});

routes.js

'use strict';

var express = require("express");
var router = express.Router();
var Question = require("./models").Question;

router.param("id", function(req, res, next, id){
    Question.findById(id, function(err, doc){
        if(err) return next(err);
        if(!doc) {
            err = new Error("Not Found");
            err.status = 404;
            return next(err);
        }
        res.question = doc;
        return next();
    });
});

router.param("aID", function(req, res, next, id){
    req.answer = req.question.answers.id(id);
    if(!req.answer){
        err = new Error("Not Found");
        err.status = 404;
        return next(err);
    }
});    

//GET /questions //this one works
router.get("/", function(req, res, next){
    //return all questions
    Question.find({})
                .sort({createdAt: -1}) 
                .exec(function(err, questions){
                    if(err) return next(err);
                    res.json(questions);
                });
    //res.json({response: "You sent a GET req"});
});

//POST /questions //this one works
router.post("/", function(req, res, next){
    var question = new Question(req.body);
    question.save(function(err, question){
        if(err) return next(err);
        res.status(201);
        res.json(question);
    });
    //return all questions
});

//GET /questions/:qid //gives 200 but doesn't show anything
router.get("/:id", function(req, res){
        res.json(req.question);
    })
    res.json({
        response: "You sent a GET req for ID "+ req.params.id
});


//POST /questions/:id/answers //500 error, doesn't work
router.post("/:id/answers", function(req, res, next){
    req.question.answers.push(req.body);
    req.question.save(function(err,question){
        if (err) return next(err);
        res.status(201);
        res.json(question);
    });
});

//PUT /questions/:qid/answers/:aid
//edit a specific answer
router.put('/:id/answers/:aID', function(req, res){
    req.answer.update(req.body, function(err, result){
        if(err) return next(err);
        res.json(result);
    });
});

//DELETE /questions/:qid/answers/:aid
//delete a specific answer
router.delete('/:id/answers/:aID', function(req, res){
    req.answer.remove(function(){
        req.question.save(function(err, question){
            if (err) return next(err);
            res.json(question);
        });
    });
});


//POST /questions/:qid/answers/:aid/vote-up
//POST /questions/:qid/answers/:aid/vote-down
//vote on a specific answer
router.post('/:id/answers/:aID/vote-:dir', 
    function(req, res, next) {
        if(req.params.dir.search(/^up|down$/) === -1){
            var err = new Error('Not Found');
            err.status = 404;
            next(err);
    }   else {
            req.vote = req.params.dir;
            next();
    }
}, function(req, res, next){
        req.answer.vote(req.vote, function(err, question){
            if(err) return next(err);
            res.json(question);
    });
});



module.exports = router;

models.js

'use strict';

var mongoose = require("mongoose");

var Schema = mongoose.Schema;

var sortAnswers = function(a, b) {
    //- negative if A should be before B
    //zero to leave it unchanged
    //+ if A is to be sorted after B
    if (b.votes === a.votes){
        return b.updatedAt - a.updatedAt;
    }
    return b.votes - a.votes;
}

var AnswerSchema = new Schema({
    createdAt: {type: Date, default: Date.now},
    updatedAt: {type: Date, default: Date.now},
    votes: {type: Number, default: 0}
});

AnswerSchema.method("update", function(updates, callback){
    Object.assign(this, updates, {updatedAt: new Date()});
    this.parent().save(callback);
});

AnswerSchema.method("vote", function(vote, callback){
    if(vote === "up"){
        this.votes +=1;
    } else {
        this.votes -=1;
    }
    this.parent().save(callback);
});

var QuestionSchema = new Schema({
    text: String,
    createdAt: {type: Date, default: Date.now},
    answers: [AnswerSchema]
});

QuestionSchema.pre("save", function(next){
    this.answers.sort(sortAnswers);
    next();
});

var Question = mongoose.model("Question", QuestionSchema);

module.exports.Question = Question;

Thanks, all. I looked for an hour but haven't found the error yet.

2 Answers

Hannah Mycock
Hannah Mycock
14,899 Points

You've used /:qid and /:aid in some places, but in other just used /:id. Maybe this is the problem?

Simon Sporrong
Simon Sporrong
35,097 Points

You also don't have a text property on the AnswerSchema in model.js. Don't know if that can cause your problem though.