passing name in url in nodejs - node.js

The code which i have written takes id from url and then gives me the output.
api?category=4556 here 4556 is the id.
I have one Products controller having
product_name
price
category_id:i am passing category id manually from category generated.
and in category controller i have category_name.
here i want to get in this way
api?category=games
is there any way to do so.
exports.getProducts = function(req, res) {
// Use the Prod model to find all products
/*
Prod.find(function(err, prods) {
if (err)
res.send(err);
res.json(prods);
next();
});
*/
var cat=req.query.category;
var condition = {};
if (cat) {
condition.cat_id = cat;
}
Prod.find(condition).then(function(cat) {
res.json({cat});
})
.catch((err) => {
console.log('error', err);
res.status(500).send();
});
};
This code checks for the products having cat_id similar to the id provided by url as ?category=4556
i want to check it as ?category=games ,
if there is some way please help it would be great pleasure.thanks in advance

I found one answer and this really works using populate
var cat=req.query.category;
var condition = {};
if (cat) {
condition.cat_id = cat;
}
Prod.find(condition).populate('cat_id').then(function(cat) {
res.json({cat});
})
.catch((err) => {
console.log('error', err);
res.status(500).send();
});
};
and did a bit change in Schema
var ProductSchema=new mongoose.Schema({
name:String,
category:String,
price:Number,
cat_id:{
type : mongoose.Schema.Types.ObjectId,
ref : 'Cat'
}
});
// Export the Mongoose model
module.exports=mongoose.model('Prod',ProductSchema);

You will have to retrieve first the category ID from the name that was supplied in the query.
When no category with the supplied name is found, you may want to return an empty products dataset. I also make the assumption that category name are unique.
Example :
exports.getProducts = function(req, res) {
var categoryName = req.query.category;
var condition = {};
if (categoryName) {
condition.name = categoryName;
}
Category.find(condition).then(function(categories) {
if(categories.length === 0) return {}
return Product.find({ category_id: categories[0].id })
}).then(function(products) {
res.json(products);
}).catch((err) => {
console.log('error', err);
res.status(500).send();
});
};

If you want to find correspond to your category name rather than your id then you have to do only one change. Fetch category name from request query (as currently you are fetching id from request query). Rest your code will be same.
I am thinking that your category name is unique also.
exports.getProducts = function(req, res) {
// Use the Prod model to find all products
/*
Prod.find(function(err, prods) {
if (err)
res.send(err);
res.json(prods);
next();
});
*/
var cat=req.query.categoryName;
var condition = {};
if (cat) {
condition.cat_Name = cat;
}
Prod.find(condition).then(function(cat) {
res.json({cat});
})
.catch((err) => {
console.log('error', err);
res.status(500).send();
});
};
Hope it will work for you.
Thanks.

Related

How to dynamically delete MongoDB entry using API route

I would just like to simply delete a record from a dynamically displayed list. I've tried every permutation of the backend code and ai just can't get it to work.
The backend is called like this:
async function deletePost() {
setLoading(true)
try {
await axios.delete(`/api/delete/${id}`)
alert("Post deleted")
}
catch (err) {
// notify user that something went wrong
console.log(err)
}
finally {
setLoading(false)
}
setLoading(false)
}
And /api/delete/${id} looks like this:
import { connectToDatabase } from "util/mongodb"
export default async (req, res) => {
const { id } = req.query;
console.log(id)
try {
const { db } = await connectToDatabase()
await db.collection("users").deleteOne({'_id': `ObjectId("${id}")`})
res.sendStatus(200).send({ done: true })
}
catch (error) {
return res.json({ error })
}
}
The console log shows the correct post id, the alert in the 'try' frontend code displays, but the dam post just wont delete. Can anyone offer any advice please? I have tried ".deleteOne({'_id': id})" but that does nothing either.
I believe you are searching for a string, instead of the ObjectId, so no documents match.
You can fix it by converting to ObjectId and then using the value converted, .deleteOne.
var ObjectId = require('mongodb').ObjectId;
const { id } = req.query;
const convertedObjectId = new ObjectId(id);
db.collection("users").deleteOne({_id: convertedObjectId })
Actual example from documentation:
try {
db.orders.deleteOne( { "_id" : ObjectId("563237a41a4d68582c2509da") } );
} catch (e) {
print(e);
}
Reference: MongoDB Documentation - Delete One.
Fixed problem:
app.delete("/cars/:id", async (req, res) => {
const carsId = req.params.id;
const query = { _id: ObjectId(carsId) };
const result = await carCollection.deleteOne(query);
res.send(result);
});

Can't access fields of MongoDB document in Node.Js

I'm using mongoose and express on my nodejs project.
Trying to get the data from here
app.get('/offers/:id', (req, res) =>{
//store the id from the url
var id = req.params.id;
//just a placeholder
var data = {title: "title", description:"description"};
//store the returned object in a variable
var oop = offers.findById(id, function (err, user) {
if(err){
return err;
}else{
title = user.title;
description = user.description;
this.obj = {
title:title,
description:description
}
console.log(obj)
return obj;
}
} );
console.log(oop)
res.render('single', {data:data});
});
so my idea is to grab the post id from the url, find it in the database, then display the title and description in the corresponding place on the ejs template, but for some reason I can't access the returned data, and what I get is a long list of objects that belongs to mongodb, without the presence of "title" or "description"
Try this, your code has couple of issues & also you need use .lean() to get raw Js objects rather than mongoDB documents :
app.get('/offers/:id', (req, res) => {
//store the id from the url
var id = req.params.id;
//just a placeholder
var data = { title: "title", description: "description" };
//store the returned object in a variable
offers.findById(id).lean().exec((err, user) => {
if (err) {
console.log(err);
res.send(err)
} else {
data.title = user.title;
data.description = user.description;
this.obj = {
title: title,
description: description
}
console.log(obj);
res.render('single', { data: data });
// (Or) res.render('single', { data: obj });
}
});
});
I just modified your code and added comments (all starting with "***").
app.get('/offers/:id', (req, res) =>{
//store the id from the url
var id = req.params.id;
//just a placeholder
var data = {title: "title", description:"description"};
//store the returned object in a variables
// var oop = ***no need for this, the data you want will be in the user variable.
offers.findById(id, function (err, user) {
if(err){
return err;
}else{
// ***this needs to be changed to...
// title = user.title;
// description = user.description;
// ***that...
data.title = user.title;
data.description = user.description;
// ***what's that for??
// this.obj = {
// title:title,
// description:description
// }
// ***this needs to be inside mongoose's callback
res.render('single', {data:data});
}
});
});

deleting route for an array in mongodB using node.js

var userSchema=new mongoose.Schema({
username:String,
password:String,
email:String,
tasks:[{
task: String
}]
});
This is my database schema.I want to create a delete route for the task to be removed.Can anyone tell me how to do so. Right now I am able to fetch the task id.
Here is link to my c9 project https://ide.c9.io/akspan12/newprojectworkspace
var express = require('express');
var router = express();
//I will take static values you can give dynamic values by using req.body
router.post('/Delete_User_Task',function(req,res){
var UserSchema = require('/path/to/Schema.js');//your schema model path
var username = 'akshansh123'; //assume it is present in db
//If you want to remove all task of this user and set one task as empty string your query and changes will be like below
var query = {
'username' :username
};
var changes = {
$set:{
'tasks':[{
task:''
}]
}
};
//If you completely want to remove json array tasks from user document than your query and changes will be like below
var query = {
'username' :username
};
var changes = {
$unset:{
'tasks':''
}
};
//If you want to remove particular task suppose say sleeping from user document than your query and changes will be like below
var query = {
'username' :username
};
var changes = {
$pull:{
'tasks':{
'task':'sleeping'
}
}
};
//If you want to remove selected tasks suppose say sleeping,walking,drinking from user document than your query and changes will be like below
var query = {
'username' :username
};
var changes = {
$pull:{
'tasks':{
'task':{
$in:['sleeping','walking','drinking']
}
}
}
};
UserSchema.update(query,changes,function(err,Result){
if(!err){
res.send('Successfully Removed tasks');
}else{
res.send('something went wrong');
console.log(err);
}
})
})
Hope this may solve your issue!!!
app.patch("/todo/:id",function(req,res){
User
.findById(req.user.id, function(err, foundUser) {
if(err){
req.flash("error",err.message);
console.log(err);
return res.redirect("back");
} if(!foundUser) {
req.flash("error","User not found");
return res.redirect("back");
} else {
foundUser.update({$pull: {tasks: {_id: req.params.id}}}, function(err) {
if(err) {
req.flash("error",err.message);
console.log(err);
return res.redirect("back");
} else {
req.flash("success","Task removed");
return res.redirect("/todo");
}
});
}
});
});
This is the delete route I used.

How to find a record in MongoDB using Node.js

I am trying to find whether my collection has a record with profilename = john and if exists I return status success if else I return fail but in my case, it is returning success for both cases.I am new to node and mongo can any one help me.
My function,
exports.searchprofilename = function (req, res) {
var params = req.params;console.log(req.params.id);
var record= db.collection('profile');
record.find({profilename:params.id}, (err, result) => {
if (err){ return console.log(err)
}
if(!result){
data = {status:'success'};
} else{
data = {status:'profile name already exists'};
}
res.send(data);
});
};
If you are only checking if a record exists, you should be easily able to do it using db.collection.count() method and checking if the number of records = 0 or not.
https://docs.mongodb.com/manual/reference/method/db.collection.count/
Honestly, I am way new to mongodb and I still cannot grasp the idea of cursors which is the return type of db.collection.find() as per https://docs.mongodb.com/manual/reference/method/db.collection.find/
I cleared it by changing find({}) to findOne({}),Thank you every one.
If your query matches then it means you have record then return Success
exports.searchprofilename = function (req, res) {
var params = req.params;console.log(req.params.id);
var record= db.collection('profile');
record.find({profilename:params.id}, (err, result) => {
if (err){ return console.log(err)
}
// If record exist then return 'Success'
if(result.length>0){
data = {status:'success'};
} else{
data = {status:'profile name already exists'};
}
res.send(data);
});
};
I think in your case, req.params.id is a String for example '123', but in your mongodb profilename field is stored as an Number.
So you can try this:
change {profilename:params.id} to {profilename:parseInt(params.id)}
Try this
exports.searchprofilename = function (req, res) {
console.log("PARAMS",req.params.id);
var data = {};
profile.findOne( {profilename:req.params.id} , function (err, fetchDataObj) {
if (err) {
console.log(err)
return err;
} else {
data.status = 'success';
data.result = fetchDataObj;
return data;
}
}).lean(true)
});
Try to Debug. the type of result is array, so try to check the length of it:
if(result.length==0){
data = {status:'success'};
} else{
data = {status:'profile name already exists'};
}

Node js crash with multiple update (mongoose)

I use this code in my controller to update one or more projects in my DB.
update: function(req, res) {
var ids = new Array();
for(var i =0;i<req.body.data.length;i++){
ids.push(req.body.data[i]._id);
}
ids.forEach(function (id,index) {
dayModel.findOne({_id: id}, function(err, day){
if(err) {
console.log("error");
}
if(day) {
day.worker = req.body.data[index].lav_mail ?
req.body.data[index].lav_mail : day.worker;
day.date = req.body.data[index].date ?
req.body.data[index].date : day.date;
day.hours = req.body.data[index].ore ?
req.body.data[index].ore : day.hours;
day.project = req.body.data[index].progetto ?
req.body.data[index].progetto : day.project;
day.activity = req.body.data[index].attività ?
req.body.data[index].attività : day.activity;
try {
day.save(function(err, day){
//return res.json(day);
});
}catch(ex){
console.log(ex.stack);
}
}
});
});
}
Then in the router
router.put('/', function(req, res) {
dayController.update(req, res);
});
When a user makes a lot of calls, NodeJS crashes.
Do you have any suggestion?
Although you can use async module there is a way without it.
Following code will update one record after another and when done it will return array of days.
update: function(req, res) {
var days = [];
updateOne();
function updateOne(){
// get one data object from array
var data = req.body.data.pop();
dayModel.findOne({_id: data.id}, function(err, day){
if(err) {
console.log("error");
}
if(day) {
...
day.save(function(err, day){
days.push(day);
// if no more data then return
if(!req.body.data.lenght) return res.json(days);
// otherwise update another one
updateOne();
});
}
});
}
}

Resources