Deleting orders works, deleting coffees doesn't. Identical functions - node.js

I have to build a CRUD in nodejs+express+mongodb and I have a function to delete orders, which is successfully deleting orders by a parameter, and a copy of this function adapted to "coffees" MongoDB collection.
The second returns undefined, or simply {}.
First I modified the collection and then different sources as arguments.
Here is server.js
// This code works.
app.delete('/orders/:coffee_id', (req, res) => {
db.collection('orders').findOneAndDelete({name: req.body.coffee_id}, (err, result) => {
if (err) return res.send(500, err)
res.json('Order deleted')
})
})
// Orders Collection. This means visiting localhost:3000/orders/Delta returns Order deleted
// Code not working as expected:
app.delete('/coffees/:id', (req, res) => {
db.collection('coffees').findOneAndDelete({'name': req.body.name}, (err, result) => {
console.log(res.body) // returns undefined.
if (err) return res.send(500, err)
res.json(req.body)
})
})
Coffees collection. Can't delete from this table. Postman DELETE to localhost:3000/coffees/Jamaica returns {} and console.log(res.body) returns undefined
Does anybody see something wrong? Please let me know if you require more code.
Thanks in advance.

A couple of things to note here.
1) Your routes are configured with path parameters, but you're trying to reference properties from req.body. I'm not sure how this is working in the first route, but I expect that it should not. You should be using req.params to access the path parameters.
app.delete('/orders/:coffee_id', (req, res) => {
db.collection('orders').findOneAndDelete({name: req.params.coffee_id}, (err, result) => {
...
})
})
2) In the second route you've declared a path parameter id, but you're attempting to access a property called name. This is where the implementation differs from the "working" route. It's not clear at face value if you want to use the ObjectId of document to perform deletions, or if you were planning using the name of the document.
Using the ObjectId:
app.delete('/coffees/:id', (req, res) => {
db.collection('coffees').findOneAndDelete({_id: req.params.id}, (err, result) => {
...
})
})
Using the name:
app.delete('/coffees/:name', (req, res) => {
db.collection('coffees').findOneAndDelete({name: req.params.name}, (err, result) => {
...
})
})
The takeaway here is that you must use the same value to reference the path param as the value declared in the path param.
/coffees/:id => req.params.id (not req.params.name)

Apparently I had to define a ObjectId like
var ObjectId = require('mongodb').ObjectID; //Include ObjectId
//then
app.delete('/coffees/:id', (req, res) => {
db.collection('coffees').findOneAndDelete({'_id': ObjectId(req.params.id)}, (err, result) => {
console.log(result)
if (err) return res.send(500, err)
res.json(result.body)
})
})

Related

Retrieving data from mongoDB using a field

I want to retrieve all the datas from my mongo db collection "Assets" whose "chapterName" is equal to the string sent through the url, How to get it?
app.get(`/api/assets/get_all/${chapterName}`, (req, res) => {
Assets.find({}, (err, assets) => {
if (err) return res.status(400).send(err);
res.status(200).send(assets);
});
});
the chapterName will be in params of request, req. let's say chaptername is present in mongoose schema.
app.get('/api/assets/get_all/:chapterName}', (req, res) => {
Assets.find({ chaptername: req.params.chapterName }, (err, assets) => {
if (err) return res.status(400).send(err);
res.status(200).send(assets);
});
});

Mongoose and Express, How can I get unique records from db?

In my database, I have 2-3 records with title (Article one).
How can I get only 1 result?
Following is my code that doesn't work,
app.get('/', (req, res) => {
Article.find.distinct(title, (err, title) => {
if(err){
console.log(err);
} else {
console.log(articles);
res.render('index', {
title: 'Articles',
articles: title
});
}
});
});
But if I use,
Article.find({}, (err, title)
it works, but I do not need objects because they are all unique
I tried this link
How do I query for distinct values in Mongoose?
But it does not work for me.
For example, I have records:
One, Two, One
But need output: One, Two
You need to use distinct operator with the desired property (here, title) passed as parameter like this,
app.get('/', (req, res) => {
Article.distinct('title', function(error, titles) { //see the use of distinct
if (err) {
console.log(err);
} else {
console.log(articles);
res.render('index', {
title: 'Articles',
articles: titles
});
}
});
});
The following query will return an array of title, all distinct.
Hope this resolves the issue.

Cloud Datastore and Node.js: Cannot get entity

I am using App Engine flexible environment with Node.js and am trying to store and retrieve entities in Cloud Datastore.
The following code successfully creates a new Event Entity:
/* Create event */
router.post('/', function(req, res, next) {
const eventKey = datastore.key('Event');
datastore.save({
key: eventKey,
data: req.body
})
.then(() => {
console.log('New event created');
res.json({id: eventKey.id});
})
.catch((err) => { next(err); });
});
However, the following returns an empty array when I provide the previously returned id:
/* Get an event */
router.get('/:id', function(req, res, next) {
console.log(req.params.id);
var eventKey = datastore.key(['Event', req.params.id]);
datastore.get(eventKey)
.then((event) => {
console.log(event);
res.json(event);
})
.catch((err) => { console.log(err); next(err); });
});
I seem to be using datastore.get correctly and to do what the docs is telling me to do.
Any idea why I cannot get the entity I previously created?
It's worth noting that Cloud Datastore keys ([Ancestor path +] kind + id/name) treat integers (id) and strings (name) differently. That is to say that the following 2 keys refer to different entities:
Key(Event, 1234)
Key(Event, "1234")
I'm not a node expert, but is it possible it is writing and reading these different keys?
parseInt can solve this:
/* Get an event */
router.get('/:id', function(req, res, next) {
console.log(req.params.id);
var eventId = parseInt(req.params.id, 10)
var eventKey = datastore.key(['Event', eventId]);
datastore.get(eventKey)
.then((event) => {
console.log(event);
res.json(event);
})
.catch((err) => { console.log(err); next(err); });
});

GET request for specific id returning null

I'm attempting to build a simple CRUD application using express and mongodb. My GET request for all database entries is working and my POST request is working but I can't seem to figure out the problem with my GET request for individual entries.
Server.js GET request:
app.get('/api/:id', function (req, res) {
var id = req.params.id;
db.collection('api').findOne({_id: id}, (err, result) => {
if (err){
res.sendStatus(404);
return console.log(err);
}
res.redirect('/');
return console.log(result);
});
});
When I type 'url/api/593555074696601afa192d7f' which is an ID I know exists the console.log is returning null, I'm not sure if I'm doing something wrong?
You should pass ObjectID instance in the query.
let ObjectID = require("mongodb").ObjectID;
app.get('/api/:id', function (req, res) {
var id = req.params.id;
db.collection('api').findOne({_id: ObjectID(id)}, (err, result) => {
if (err){
res.sendStatus(404);
return console.log(err);
}
res.redirect('/');
return console.log(result);
});
});
Give Mongoose a try. It might be of help if your models get complex.

Mongoosedb: query by username

Problem Question: I am using MongooseDB with Nodejs and I have user schema
var UserSchema = new mongoose.Schema({
userEmail: String
});
how would I query using the userEmail?
I tried following but no result. On my postman i get cast to ObjectId failed error
router.get('/:userEmail', function(req, res, next) {
User.find(req.params.userEmail, function (err, userDetails) {
if(err){
return next(err);
}res.json(userDetails);
})
});
You need to create a query object or document that has the userEmail property and a value from the req.params object. In your case, this would be:
router.get('/:userEmail', function(req, res, next) {
User.find({ "userEmail": req.params.userEmail }, function(err, userDetails) {
if(err){
return next(err);
}
res.json(userDetails);
});
});
Please try this syntax
router.get('/:userEmail', function(req, res, next) {
User.find({"userEmail":req.params.userEmail}, function (err, userDetails) {
if(err){
return next(err);
}res.json(userDetails);
})
});
You have to put condition on which field you want to query data.
I am unable to reproduce your error "ObjectId failed error". However, I am adding another answer to give you more options.
The following things are slightly different from other answers:-
1) "lean()" is used to ensure that you will be returned a plain JavaScript object
2) Excluded the "_id" from JSON response though I am not sure whether you need the "Id" in the response. This is just to check whether "id" in response is causing the problem.
router.get('/:userEmail', function(req, res, next) {
User.find({"userEmail": req.params.userEmail}, {"_id":false}).lean().exec(function(err, users) {
if (err) {
return next(err);
}
console.log(users);
res.json(users);
});
});

Resources