Hi i have end point to post data to mongodb , when i submit a form only ID is submitted I think because am using insert instead of save ,
Here is how it looks:
app.post('/comments', (req, res) => {
const { errors, isVal } = validate(req.body);
if (isVal){
const { author, description } = req.body;
db.collection('comments').insert({ author, description }, (error, result) => {
if (error) {
res.status(500).json({ errors: { global: "Oops something is right!" }});
} else {
res.json({ comments: result.ops[0] });
}
})
} else {
res.status(400).json({ errors });
}
});
The method above is the one saves only ID, other data saved null: I tried to change like this, replacing insert with save some one suggested something like this.
app.post('/comments', (req, res) => {
const { errors, isVal } = validate(req.body);
if (isVal){
const { author, description } = req.body;
db.collection('comments').save({ author, description }, (error, result) => {
if (error) {
res.status(500).json({ errors: { global: "Oops something is right!" }});
} else {
res.json({ comments: result.ops[0] });
}
})
} else {
res.status(400).json({ errors });
}
});
Still the same : here is the result saved in database:
{
"_id": {
"$oid": "5b281457f5b629565c09ce26"
},
"author": null,
"description": null
}
how can I change my method so that it can use save instead of insert?
and what is the different between save and insert in mongodb?
Try with this
let newcollection = db.collection('comments');
newcollection.insert({})
Related
I have a user schema as follows:
const UserSchema = new mongoose.Schema({
skills: [String]
});
module.exports = mongoose.model("User", UserSchema);
And a Fetch request to delete a skill as follows:
const deleteItem = async (id) => {
try {
await fetch(`http://localhost:5000/api/user/deleteskill`, {
method: "DELETE",
headers: { "Content-Type": "application/JSON", token: accessToken },
body: JSON.stringify({ userid: userid , skill:id}),
})
.then((res) => res.json())
.then((data) => {
console.log("USER SKILLS:", data.userskills);
});
} catch (err) {
console.log(err);
}
};
Server
const deleteSkill = async (req, res) => {
try {
const user = await User.findById(req.body.userid)
//user.skills.pull(req.body.skill);
// removeskill = user.skills.filter(function(item) {
// return item !== req.body.skill
// })
if (user.skills.includes(req.body.skill)) {
res.status(400).json("Item Still Exists");
} else {
res.status(200).json("Item Deleted");
}
} catch (error) {
res.status(500).send({ error: error.message });
}
};
the array is in the following structure
[
'skill1', 'java', 'skill5'
]
I have tried to remove the user skill from the array in several ways but I still get res.status(400).json("Item Still Exists");. What I'm doing wrong?
Use the findOneAndUpdate method to find a document with the user id and update it in one atomic operation:
const deleteSkill = async (req, res) => {
try {
let message = "Item Deleted";
let status = 200;
const user = await User.findOneAndUpdate(
{ _id: req.body.userid },
{ $pull: { skills: req.body.skill } },
{ new: true }
)
if (user && user.skills.includes(req.body.skill)) {
message = "Item Still Exists";
status = 400;
} else if (!user) {
message = "User Not Found";
status = 404;
}
res.status(status).send({ message });
} catch (error) {
res.status(500).send({ error: error.message });
}
};
I believe you want to remove skills from the database then the following function could help you out.
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, function(err, db) {
if (err) throw err;
var dbo = db.db("mydb");
var myquery = { userid: userid, skillid: skillid};
dbo.collection("skills").deleteOne(myquery, function(err, obj) {
if (err) throw err;
console.log("1 document deleted");
db.close();
});
});
You have a method of removing elements from arrays, if you want to remove the first one you could use array.shift (more on it here), but if you want to delete it completely from your database you could always, find it and then update it.
User.update({ _id: userid }, { $pull: { "skills": "[skill]" }})
updateProfile: async function(req, res) {
try {
const update = req.body;
const id = req.params.id;
if (!req.files || Object.keys(req.files).length === 0) {
return res.status(400).send('No files were uploaded.');
}
const image = req.files.profileImage;
const cloudFile = await upload(image.tempFilePath);
const profileImage = cloudFile.url
console.log('Loging cloudfile', profileImage)
await User.updateOne(id, { update }, { profileImage }, { new: true },
function(err, doc) {
if (err) {
console.log(err)
}
if (doc) {
return res.status(200).send({ sucess: true, msg: 'Profile updated successful' })
}
});
} catch (error) {
res.status(500).json({ msg: error.message });
}
}
But I'm getting an error of "Callback must be a function, got [object Object]"
I have tried to $set: update and $set: profileImage but still not working.
So the image successful upload into the cloudinary but the update for mongoose is not working.
Upon brief research into the issue, I think you are feeding the arguments in wrong. Objects can be confusing but not to worry.
Your code is:
await User.updateOne(id, { update }, { profileImage }, { new: true }
However, I believe it should be something more like:
await User.updateOne({id: id}, { profileImagine: profileImage, new: true },
The API reference annotates use of the function as:
const filter = { name: 'John Doe' };
const update = { age: 30 };
const oldDocument = await User.updateOne(filter, update);
oldDocument.n; // Number of documents matched
oldDocument.nModified; // Number of documents modified
I am trying to build a nodejs app with mysql and what I want is
that my controllers and messages that I send should be in separate file
as shown below
this is my auth controller file
exports.signup = (req, res) => {
try {
const { name, username, email, phone_number, gender } = req.body;
const payload = [name, username, email, phone_number, gender];
connection.query(signupUserQuery, payload, (error) => {
if (error) {
return errorMessage('Signup Failed');
} else {
return createdMessage('Signup SuccessFul');
}
});
} catch (error) {
return errorMessage('Signup Failed');
}
};
and this is my messages file where I keep my messages
module.exports = {
createdMessage: function (message) {
return res.status(201).json({
isError: false,
message: message,
});
},
errorMessage: function (message) {
return res.status(500).json({
isError: true,
message: message,
});
},
};
So what I want is I want to return this function whenever controller is executed but the problem is when I try to do this I got error as res is not defined ,
So is there any way to use res in this messages.js File
What I have tried is I send res object from controller and that works but that is repetitive and I do not want to repeat myself
And one more thing I write my queries in separate file link this
insert into tbl_user (name,username,email,phone_number,gender) values (?,?,?,?,?)
but here the problem is I have to put question marks according to fields I require
so is there any way to do that in single question mark ?
You can use it like this.
This is your messages.js file.
function createdMessage (message) {
return {
isError: false,
message: message
}
}
function errorMessage (message) {
return {
isError: true,
message: message
}
}
module.export = {
createdMessage,
errorMessage
}
This is auth controller.js
const { createdMessage, errorMessage } = require("./messages.js");
exports.signup = (req, res) => {
try {
const { name, username, email, phone_number, gender } = req.body;
const payload = [name, username, email, phone_number, gender];
connection.query(signupUserQuery, payload, (error) => {
if (error) {
return res
.status(400)
.send(errorMessage('Signup Failed'));
} else {
return res
.status(201)
.send(createdMessage('Signup SuccessFul'));
}
});
} catch (error) {
return res
.status(400)
.send(errorMessage('Signup Failed'));
}
};
I am trying to extend the amount of fields that our API is returning. Right now the API is returning the student info by using find, as well as adding some information of the projects by getting the student info and using findOne to get the info about the project that the student is currently registered to.
I am trying to add some information about the course by using the same logic that I used to get the project information.
So I used the same findOne function that I was using for Projects and my logic is the following.
I created a variable where I can save the courseID and then I will put the contents of that variable in the temp object that sending in a json file.
If I comment out the what I added, the code works perfectly and it returns all the students that I require. However, when I make the additional findOne to get information about the course, it stops returning anything but "{}"
I am going to put a comment on the lines of code that I added, to make it easier to find.
Any sort of help will be highly appreciated!
User.find({
isEnrolled: true,
course: {
$ne: null
}
},
'email pantherID firstName lastName project course',
function(err, users) {
console.log("err, users", err, users);
if (err) {
return res.send(err);
} else if (users) {
var userPromises = [];
users.map(function(user) {
userPromises.push(new Promise(function(resolve, reject) {
///////// Added Code START///////
var courseID;
Course.findOne({
fullName: user.course
}, function(err, course) {
console.log("err, course", err, course);
if (err) {
reject('')
}
courseID = course ? course._id : null
//console.log(tempObj)
resolve(tempObj)
}),
///// ADDED CODE END //////
Project.findOne({
title: user.project
}, function(err, proj) {
console.log("err, proj", err, proj);
if (err) {
reject('')
}
//Course ID, Semester, Semester ID
//map to custom object for MJ
var tempObj = {
email: user.email,
id: user.pantherID,
firstName: user.firstName,
lastName: user.lastName,
middle: null,
valid: true,
projectTitle: user.project,
projectId: proj ? proj._id : null,
course: user.course,
courseId: courseID
}
//console.log(tempObj)
resolve(tempObj)
})
}))
})
//async wait and set
Promise.all(userPromises).then(function(results) {
res.json(results)
}).catch(function(err) {
res.send(err)
})
}
})
using promise could be bit tedious, try using async, this is how i would have done it.
// Make sure User, Course & Project models are required.
const async = require('async');
let getUsers = (cb) => {
Users.find({
isEnrolled: true,
course: {
$ne: null
}
}, 'email pantherID firstName lastName project course', (err, users) => {
if (!err) {
cb(null, users);
} else {
cb(err);
}
});
};
let findCourse = (users, cb) => {
async.each(users, (user, ecb) => {
Project.findOne({title: user.project})
.exec((err, project) => {
if (!err) {
users[users.indexOf(user)].projectId = project._id;
ecb();
} else {
ecb(err);
}
});
}, (err) => {
if (!err) {
cb(null, users);
} else {
cb(err);
}
});
};
let findProject = (users, cb) => {
async.each(users, (user, ecb) => {
Course.findOne({fullName: user.course})
.exec((err, course) => {
if (!err) {
users[users.indexOf(user)].courseId = course._id;
ecb();
} else {
ecb(err);
}
});
}, (err) => {
if (!err) {
cb(null, users);
} else {
cb(err);
}
});
};
// This part of the code belongs at the route scope
async.waterfall([
getUsers,
findCourse,
findProject
], (err, result) => {
if (!err) {
res.send(result);
} else {
return res.send(err);
}
});
Hope this gives better insight on how you could go about with multiple IO transactions on the same request.
I am creating a rest api I have end point for Post/Movies: Request body should contain only movie title, and its presence should be validated Based on passed title, other movie details should be fetched from thememoviedb,and saved to application database.
app.post('/movies', (req, res) => {
request('https://api.themoviedb.org/3/discover/movie?callback=JSONP_CALLBACK&sort_by=popularity.desc&api_key=2931998c3a80d7806199320f76d65298', function (error, response, body) {
console.log('error:', error); // Print the error if one occurred and handle it
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
});
db.collection('movies').findOneAndUpdate(req.body.title,{
title: 'Avengers',
},(err, result) => {
if (err) {
res.send({
'error': 'An error has occured'
});
} else {
res.send(result.ops[0]);
}
});
});
when I run the app I get this error, what am I doing wrong here,? am new to nodejs and all this stuff just learning
Use $eq operator in the filter object $eq
{ <field>: { $eq: <value> } }
So the final snippet becomes like this:
app.post('/movies', (req, res) => {
/* code ... */
let { title } = req.body
db.collection('movies').findOneAndUpdate({ title: { $eq: title } }, { title: 'Avengers' }, (err, result) => {
if (err) {
res.send({ 'error': 'An error has occured' });
} else {
res.send(result.ops[0]);
}
});
});
Try the following,
db.collection('movies').findOneAndUpdate({title:req.body.title},{
$set:{
'Avengers'
}})