The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

537960 (7) [Avatar] Offline
#1
Hello,
I am trying to replicate the steps for adding reviews outlined in the later part of chapter 7, but instead of reviews, whole new locations. A 400 error keeps occurring and I cannot seem to find the bug. I have included the controller below.

Any direction or insight would be fantastic.

Thank you.
Dan

const _renderAddLocation = function (req, res) {
res.render('add-location', {
title: 'Add location',
pageHeader: { title: 'Add location' }
});
};
const addNew = function(req, res){
_renderAddLocation(req, res);
};
const locationsCreate = function(req, res){
const path = `/api/locations`;
const postdata = {
title: req.body.title,
description: req.body.description,
lead: req.body.lead,
teamMembers: req.body.teamMembers,
outcomes: req.body.outcomes,
completion: req.body.completion
};
const requestOptions = {
url : apiOptions.server + path,
method : 'POST',
json : postdata
};
request(
requestOptions,
(err, response, body) => {
if (response.statusCode === 201) {
res.redirect(`/`);
} else {
_showError(req, res, response.statusCode);
}
}
);
};
Clive.Harber (13) [Avatar] Offline
#2
Hi

Thanks for your query. I'm Clive, I've been asked to co-author this title.

You've shown the request part of conversion, but I can't see the handler code that you've created. If you're receiving a 400 Bad Request response, then something at the server level is not happy.

Could you post the api code being used to handle this request and I'm sure we'll be able to come up with an answer for you.

Thanks

Clive
537960 (7) [Avatar] Offline
#3
Huge Thank You Clive.

Really appreciate all that you are doing to complete the book.

Here is my API code:
app_api/controllers/locations.js

//To include the model use Mongoose
//This first line gives the controllers access to the db connection.
const mongoose = require('mongoose');
//This second line brings in the location model to allow interaction with the Locations collection.
//Loc is the name
const Loc = mongoose.model('Location');

//Need error handling for this controller
const locationList = function (req, res) {
Loc
.find(req.params.locations)
.exec((err, locations) => {
res
.status(200)
.json(locations);
});
};

//Creating new docs in MongoDB with Mongoose
const locationsCreate = function (req, res) {
Loc.create({
title: req.body.title,
description: req.body.description,
lead: req.body.lead,
teamMembers: req.body.teamMembers,
goal: req.body.goal,
completion: req.body.completion
}, (err, location) => {
if (err) {
res
.status(400)
.json(err);
} else {
res
.status(201)
.json(location);
}
});
};

const locationsReadOne = function (req, res) {
//Adding error trapping
if (req.params && req.params.locationid){
Loc
//The .findById method below accepts a single parameter, the ID to look for.
.findById(req.params.locationid)
//The exec method executes the query and passes a callback function that runs when operation is complete.
//There are two params err and the instance of the found doc
.exec((err, location) => {
if (!location) {
res
.status(404)
.json({
"message" : "locationid not found"
});
return;
} else if (err) {
res
.status(404)
.json(err);
return;
}
res
.status(200)
.json(location);
});
} else {
res
.status(404)
.json({
"message" : "No locationid in request"
});
}
};

const locationsUpdateOne = function (req, res) {
if (!req.params.locationid) {
res
.status(404)
.json({
"message" : "Not found, locationid is required"
});
return;
}
Loc
.findById(req.params.locationid)
.select('-title -lead')
.exec((err, location) => {
if (!location) {
res
.json(404)
.status({
"message" : "locationid not found"
});
return;
} else if (err) {
res
.status(400)
.json(err);
return;
}
location.title = req.body.title;
location.description = req.body.description;
location.lead = req.body.lead;
location.team = req.body.team;
location.outcomes = req.body.outcomes;
location.completion = req.body.completion
},
location.save((err, location) => {
if (err) {
res
.status(404)
.json(err);
} else {
res
.status(200)
.json(location);
}
})
)
};



module.exports = {
locationsList,
locationsCreate,
locationsReadOne,
locationsUpdateOne
};

And the app_api/models/locations.js

const mongoose = require('mongoose');

//Everything is derived from a schema so here is a reference to the schema and the definition of the location
//Each scehma maps to a MongoDb collection and def the doc shape
const locationSchema = new mongoose.Schema({
//Here are the keys which define a property
//So property title is cast to the string schema type
title: {type: String, required: true},
description: {type: String, required: true},
lead: {type: String, required: true},
teamMembers: {type: String, required: true},
goal: {type: String, required: true},
completion: {
type: Date,
required: true
},
});
//Here the schema is compiled into a model
mongoose.model('Location', locationSchema);
Clive.Harber (13) [Avatar] Offline
#4
From your listing, it looks like you're sending an outcomes element in your POST data, but the mongoose model is expecting a 'goal' element which is required but is not in the send or in the API controller receiving the request. This is most likely the cause of the 400 Bad Request response that you're getting.

Cheers
Clive
Author
537960 (7) [Avatar] Offline
#5
Hi Clive,
Thank you so much, nice catch. I modified those files plus the removing the 'required' from a couple of key value pairs in the app_api/models/locations.js file .

Unfortunately nothing changed. I do not get a 400 though so it seems to be acting as if everything is as it should. Maybe something wring with my pug file code and the button as in the terminal the GET api/locations 200 is returned.

I'm going to go through the files again to see is there are other errors.

Thank you again.
Best,
Dan

Clive.Harber (13) [Avatar] Offline
#6
It's not a problem. Let me know if you continue to be stuck and I'll see what I can do to help.

Cheers

Clive
537960 (7) [Avatar] Offline
#7
Many Thanks Clive!

Perhaps there will be a solution through Angular.

Best,
Dan