I am struggling to understand where and why I initialize my first newFruit in my .then() promise or where it is coming from in my controller JS file. I am working on an express / mongo DB API
Please explain .then line
const Recipe = require("../models/recipes.models");
module.exports.createRecipe = (req, res) => {
Recipe.create(req.body)
.then((newFruit) => res.json(newFruit))
.catch((errors) => res.status(400).json(errors));
};
What I think i understand currently is that my newFruit is equal to my req.body post information object and i am setting that as a successful json response for my API.
However I am confused on the flow of data and what my first newFruit does and why I need it. Does the req.body form Data just automatically get renamed to whatever I call it in my .then ?
Any Pseudo Code may help.
console log of newFruit from postman form
{
name: 'soup',
under30: true,
price: 400,
_id: new ObjectId("636d649d85c3df316383c409"),
createdAt: 2022-11-10T20:52:45.733Z,
updatedAt: 2022-11-10T20:52:45.733Z,
__v: 0
}
Related
I am trying to update MongoDB database with mongoose
Works but I can't get a call back with new data
Templates.updateOne((req.query, req.body))
does not work
Templates.updateOne(req.query, req.body, { new: true }, (err, data) => {
console.log("just call back", data);
})
the data that is coming from req.query
{title: "Hello World"}
the data that is coming from req.body
{_ref: "your ref}
I am hoping to be able to update with callback and new data to console.log
According to the doc, Document.prototype.updateOne() does not accept {new:true} (it is a native MongoDB command, I believe), but Model.findOneAndUpdate() does.
I'm trying to add a new route to fetch a user by id but my error handling is not working correctly. Here is the code for that route.
const express = require('express');
require('./db/mongoose');
const User = require('./models/user');
const Task = require('./models/task');
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json());
// ***removed code for brevity
// Route for fetching user by id
app.get('/users/:id', (req, res) => {
//console.log(req.params.id);
const _id = req.params.id;
User.findById(_id)
.then(user => {
//console.log(user)
if (!user) {
return res.status(404).send();
}
res.send(user);
})
.catch(e => {
res.status(500).send();
});
});
So if I test the route on Postman and I enter the correct user id from the database I get that user sent back, which is the the correct response. But if I enter an incorrect user id I get the 500 error code response instead of the 404 error code. The if (!user) statement is getting skipped and I can't figure out why. Any thoughts as to what I am missing?
Running this thru my own personal mongoose/express-using project, I get the following error:
UnhandledPromiseRejectionWarning: CastError: Cast to ObjectId failed for value "12345" at path "_id" for model "User"
That basically means Mongoose is expecting its own specific object type, an "ObjectId". This is a bit of a pain, since normally if you're using .findOne({_id:something), you can just use a string. If we do:
User.findById(mongoose.Types.ObjectId(_id))
it should work. Note that if you use an invalid id (like I obviously did here, it'll still error out. For that reason, I'd use the standard NodeJS format for callbacky stuff:
.then((err,result)=>{
//other stuff
});
In general, the .catch() block should only happen if obviously Mongoose and your router can't handle it.
EDIT: Also, for others info, Mongoose.model.findById is a built-in convenience method, and should basically do exactly what it says on the tin.
I'm using Angular-Fullstack generator, and I'm not able to get a list of drivers depending on a companyID, through $resource query. This is what I have:
server/api/driver/index.js:
router.get('/:company', controller.index);
server/api/driver/driver.controller.js:
export function index(req, res) {
return Driver.find({company: req.params.company}).exec()
.then(function(res){
console.log(res); /* I get here the result correctly */
respondWithResult(res)
})
.catch(handleError(res));
}
client/services/driver.service.js:
export function DriverResource($resource) {
'ngInject';
return $resource('/api/drivers/:id/:company', {company: '#_id'});
}
client/app/driver/driver.controller.js:
this.driverList = Driver.query({company: Auth.getCurrentUser()._id}});
console.log(this.driverList); /* Empty array */
I'd be grateful if someone could help me getting the response from the server...
Thank you in advance.
I just realised that I was duplicating the 'res' variable:
server/api/driver/driver.controller.js:
export function index(req, res) {
return Driver.find({company: req.params.company}).exec()
.then(function(**res**){
/* Should be the result, not the response */
console.log(**res**);
respondWithResult(**res**)
})
.catch(handleError(res));
}
You were close.
Driver.query({company: 'foo'}).$promise.then(function(results) {
console.log(results) //here
}, function(err) {
//here is your 404 error, but you should create an http interceptor
});
It's async, do you don't get your results right away.
This will work of course, assuming your backend responds properly.
EDIT: Your backend is missing some endpoints. You should be able to respond to requests to /api/drivers/ with a list of drivers
EDIT 2:
Angular's resource will give you access to some methods:
Driver.get(1) Will make a request to /api/drivers/:id and will be expecting the backend to respond with an object representing the driver with said ID. This should be used when you want to fetch only 1 record
Driver.query({foo: 'bar', some_id: 1}) Will make a request to /api/drivers?foo=bar&some_id=1 and will be expecting the backend to respond with an array of objects, each representing a driver. This should be used when you want to fetch several records, for example in an index.
Driver.query() will make a request to /api/drivers and will be expecting the backend to respond with an array
Driver.create(data) will make a POST request to /api/drivers and will expect an object (the created driver) in the response. Used to create a new record
There are some others, this is the ones I use.
So, your backend, considering you are using this three methods, needs to handle:
router.get('/drivers/:id', function(req, res) {
let id = req.params.id
})
router.get('/drivers', function(req, res) {
//if request was /drivers?foo=bar
let foo = req.query.foo
})
router.post('/drivers', function(req, res) {
let body = req.body
})
As I said, there are several things in play here. If you are at a lost, break the problem into pieces. Get the backend working before going to Angular.
I am trying to update a record in mlab, a remote mongodb database. I am using express, mongoose and nodejs to update a certain record. I also use promises to avoid the callback pyramid.
Api file:
router.put('/chairs/:id', function(req, res, next){
Chair.findByIdAndUpdate({id:req.params.id}, req.body)
.then(function() {
Chair.findOne({id:req.params.id})
})
.then(function(chair){
res.send(chair);
})
.catch(next);
});
I tested the code above using Postman 'x-www-form-urlencoded'. When i try to UPDATE just 1 field 'title' and send PUT REQUEST , I am prompted with
{
"myError": "Cast to ObjectId failed for value \"{ id: '5953532df36d28458af5609f' }\" at path \"_id\" for model \"chair\""
}
I want to update a record and get the ID again and print the updated record.
Please help. I am not sure how to properly nest my promises
I have a search api that you can search using the imgur api and it'll return json data of the images, but will also record your latest search in the "/latest" url. The only problem is it returns an empty array which leads me to believe my mlab database isn't saving anything despite having a save method.
Whole file: https://github.com/jeffm64/image-search-abstraction-layer
the code that may be not allowing it: index.js
router.get("/latest", function (req, res) {
History.find({}, 'term when -_id').sort('-when').limit(10).then(function (results) {
res.json(results);
});
});
router.get("/search/:q", function (req, res) {
imgur.getImage(req.params.q, req.query.offset).then(function (ans) {
new History({ term: req.params.q }).save();
res.json(ans);
});
});
history.js
var historySchema = new mongoose.Schema({ term: String, when: { type: Date, default: Date.now } });
var History = mongoose.model("History", historySchema);
Ok so the answer to this is super noob level. It wouldn't connect to the database because you made the user login for mlabs database read me only on accident. I guess I will leave this in case some other poor soul spends 15+ hours troubleshooting code that's probably fine!