Using two apis one with object id and another with name - node.js

I have two api calls to retrieve data from the same collection using different parameters.
The first one is by the ObjectID:
app.get('/api/employees/:id', function(req, res){
Employee.findOne({_id:req.params.id}, function(err, employee){
if(err)
res.send(err);
res.json(employee);
}); });
And the second one retrieves data by the name :
app.get('/api/employees/:name', function(req, res){
Employee.findOne({name:req.params.name}, function(err, employee){
if(err)
res.send(err);
res.json(employee);
});});
I placed both Apis in my code, but only the first one is being called. If I run my code I have something like:
{
"_id": "58b00dd47689fc2f48b9baf4",
"name": "Rohtih",
"dept": "CSE",
"area": "Banglore",
"contact": "9962938489",
"status": "System Engineer",
"salary": "30000",
"__v": 0
},
My mongo collection looks Like this:
{
"_id": "58b00dd47689fc2f48b9baf4",
"name": "Rohtih",
"dept": "CSE",
"area": "Banglore",
"contact": "9962",
"status": "System Engineer",
"salary": "30000",
"__v": 0
},
{
"_id": "58b00df07689fc2f48b9baf5",
"name": "Vaibhav",
"dept": "CSE",
"area": "Banglore",
"contact": "819",
"status": "Manager",
"salary": "300000",
"__v": 0
}
I would like to know how do I use both apis at a time? Is there a mistake in my code, please help me solving this?

As I could understand from your code, you may receive both parameters but you don't know when to use what. What I would separate in two different api calls:
First one is to find by Id:
app.get('/api/employees/findById', function(req, res){
Employee.findOne({_id:req.params.id}, function(err, employee){
if(err)
res.send(err);
res.json(employee);
}); });
Second one is to find by name:
app.get('/api/employees/findByName', function(req, res){
Employee.findOne({name:req.params.name}, function(err, employee){
if(err)
res.send(err);
res.json(employee);
});});
If you don't like any of those approaches, you can leave as it is and verify if the parameters are present, for example:
app.get('/api/employees/find', function(req, res){
let name = req.params.name;
let id = req.params.id;
if(name !== undefined) {
//Find By name here
} else if(id !== undefined) {
//Find by id here
}
}
Hope my answer was helpful.

One approach you can take is determine the value of the req.params.id string if it's a valid ObjectId and then create a query based on the outcome. For example:
app.get('/api/employees/:id', function(req, res){
var query = {};
if (mongoose.Types.ObjectId.isValid(req.params.id)) {
query._id = req.params.id;
} else {
query.name = req.params.id;
}
Employee.findOne(query, function(err, employee){
if(err)
res.send(err);
res.json(employee);
});
});

Related

To use Mongoose find() with sort() and limit()

I want to get part of the data and it works, But when I tried to use limit() & sort() query, it's not working.
I want five data sorted by date. And it should be only 'login bio avatar_url' data. to reduce data.
But there also no error message, so I cannot find where the error from.
[My Code]
let User = require('../lib/models/userModel');
router.get("/", function (req, res, next) {
console.log(`HOME ROUTE!`);
User.find({}).limit(5).sort({
created_at: -1
}), 'login bio avatar_url', (function (err, result) {
if (err) return handleError(err);
console.log(result);
res.render('main', {
dataarray: result,
_user: req.user
})
})
});
The structure of my data looks like this.
[DATA]
{
"_id": {
"$oid": "5ebbcc92ae44dd149c12faf3"
},
"login": "apple",
"id": 10639145,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjEwNjM5MTQ1",
"avatar_url": "https://avatars0.githubusercontent.com/u/10639145?v=4",
~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Cut useless data]
"name": "Apple",
"company": null,
"blog": "https://apple.com",
"location": "Cupertino, CA",
"email": null,
"hireable": null,
"bio": null,
"public_repos": 85,
"public_gists": 0,
"followers": 0,
"following": 0,
"created_at": "2015-01-21T20:19:28Z",
"updated_at": "2020-05-01T14:38:33Z"
}
When I tried to access / path, console only shows the this log.
Solved with this code. I think it's sequence problem
let User = require('../lib/models/userModel');
router.get("/", function (req, res, next) {
console.log(`HOME ROUTE!`);
User.find({},'login bio avatar_url', {limit:5}).sort({created_at:-1}).exec(function (err, result) {
if (err) console.log(err);
console.log(result);
res.render('main', {
dataarray: result,
_user: req.user
})
})
});

How to speed up node service

I have two collections categorytypes and categories, each category type has multiple categories. When I am fetching all category details in each index of category there should be a a filed of category_type giving all details of category_type.
My code is:
exports.findAllWithParentChild = (req, res) => {
let resData = [];
Models.Category.find()
.then(data => {
var results = [];
async.each(data,function(cat,callback) {
console.log(cat.categorytype_id)
Models.CategoryType.findOne({'_id' : mongoose.Types.ObjectId(cat.categorytype_id)},function(err,catType) {
var obj = cat.toObject();
obj.category_type = catType;
results.push(obj);
callback(err);
});
},
function(err) {
if (err) throw err;
res.send({
response: true,
message: "Category deleted successfully.",
data : results
});
});
});
};
And the format I need in response:
{
"_id": "5cb78c44ede6452278d13fbe",
"title": "fhhghgf",
"description": "hgfhgf",
"slug": "hgfhgfhgf",
"categorytype_id": "5cb78ba8ede6452278d13fb6",
"user_id": "hgfhgfh",
"status": true,
"created_at": "2019-04-17T20:27:48.821Z",
"updated_at": "2019-04-17T20:27:48.821Z",
"__v": 0,
"category_type": {
"_id": "5cb78ba8ede6452278d13fb6",
"title": "asde",
"description": "asde",
"slug": "asde",
"user_id": "asde",
"status": true,
"created_at": "2019-04-17T20:25:12.863Z",
"updated_at": "2019-04-17T20:25:12.863Z",
"__v": 0
}
},
Is there any better way? Thanks for your assistance.
Change your code with below one and check the output
exports.findAllWithParentChild = (req, res) => {
Models.Category.find({}).
populate('categorytypes').
exec(function (err, data) {
if (err) return handleError(err);
console.log('Success', data);
});
};

Find a specific object in array with Mongoose and Node.js

I am trying to return a specific object in an array with mongoose. My document is as follows:
{
"_id": {
"$oid": "577a9345ba1e2a1100624be7"
},
"name": "John Doe",
"password": "$2a$10$NzqAqxTRy8XLCHG8h3Q7IOLBSFCfBJ7R5JqHy1XHHYN.1h074bWJK",
"__v": 0,
"birthDate": "14.07.2016",
"academic": [
{
"about": "asdfasdf",
"to": "asdf",
"from": "asfdasdf",
"institute": "asdfasdf",
"qualification": "asdfasdf",
"_id": {
"$oid": "579111b3e68d489f1ff8b6dc"
}
}
]
}
I want to return that academic object in the list. I am passing in the institute name into the route my code is as follows:
getAcademicInstituteByName: function(req, name, cb){
User.findById(req.user.id, function (err, user) {
if(err) throw err;
if(user){
academic = user.academic.institute(name);
return cb(null, academic);
}
});
But this is not working since I am getting an error saying user.academic.institute is not a function. Any help would be greatly appreciated
user.academic.institute is an array, so you can use regular array operations to find the entry you're interested in:
var academic = user.academic.institute.filter(i => i.institute === name)
.pop();
return cb(null, academic);
academic = user.academic.institute;
this should work, though I haven't tested it.

Not getting id from other collection using mongodb and node.js

I am adding products under particular userId but not getting userId from other collection.
api.js
var insertDocument = function(db, callback) {
db.collection('proInfo').insertOne( {
"Product_Name": json.Product_Name,
"Brand": json.Brand,
"Color": json.Color,
"Image": json.Image,
"Price": json.Price,
"Rating": json.Rating,
"Description": json.Description,
"Category": json.Category,
"Url": urla,
**"userId":db.collection('users').findOne()[0]._id,**
}, function(err, result) {
assert.equal(err, null);
console.log("Inserted a document into the proInfo collection.");
callback(result);
});
};
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
insertDocument(db, function() {
db.close();
});
});
You have to request the user from the datbase after inserting it.
e.g. based on your code the following should work:
var insertDocument = function(db, callback) {
// Based on your code we assume that you have only one user in the database. Otherwise you have to do a find for a specific user.
db.collection('users').findOne(function (err, user) {
if (err) { return callback(err); }
db.collection('proInfo').insertOne( {
"Product_Name": json.Product_Name,
"Brand": json.Brand,
"Color": json.Color,
"Image": json.Image,
"Price": json.Price,
"Rating": json.Rating,
"Description": json.Description,
"Category": json.Category,
"Url": urla,
"userId": user._id
}, function(err, result) {
assert.equal(err, null);
console.log("Inserted a document into the proInfo collection.");
// Below I am passing the error as a first param to your callback. You can implemented as you wish, but it is a convention to use error as a first param.
callback(err, result);
});
});
};

Finding a MongoDB document by different types with Mongoskin

This is an example of document that I have in my MongoDB:
{
"_id": ObjectId('5525039895884d66710d0fc3'),
"prid": "63527",
"data": {
"sku": "HF22-81639",
"name": "Product Test",
"ean": "8763900872512",
"description": "This product is my first test",
}
}
I want to make several search methods, where the search criteria are search by SKU, EAN or PRID. I created the methods but do not work, this is the example of one of the methods that I created and it does not work, just find the first document of my database but without any search criteria.
This search for "_id" if it works perfectly:
// GET - "_id"
app.get("/:id", function(req, res, next) {
req.collection.findOne({
_id: id(req.params.id)
}, function(e, result) {
if(e) return next(e);
res.send(result);
});
});
This search for "sku" does not work (this is where I need help):
// GET - "sku"
app.get("/sku/:id", function(req, res, next) {
req.collection.findOne({
sku: id(req.params.sku)
}, function(e, result) {
if(e) return next(e);
res.send(result);
});
});
Not sure how your id() function is defined but you could try:
// GET - "sku"
app.get("/sku/:id", function(req, res, next) {
req.collection.findOne({
"data.sku": req.params.id
}, function(e, result) {
if(e) return next(e);
res.send(result);
});
});
In your original code, req.params.sku is undefined because the req.params object doesn't have the field sku. From the url, only the req.param.id field is defined (from this => "/sku/:id"). So for example, if you test your API with this url:
http://localhost:3000/sku/HF22-81639
will bring back the document:
{
"_id": ObjectId('5525039895884d66710d0fc3'),
"prid": "63527",
"data": {
"sku": "HF22-81639",
"name": "Product Test",
"ean": "8763900872512",
"description": "This product is my first test",
}
}

Resources