Mongoose findOne produces no output or delivers whole database - node.js

I created a function to create a profile document, based on a schema, into mongoDB, which works so far:
const createUpdateProfile = (req, res) => {
let uuid = req.user.identities[0].id;
let provider = req.user.identities[0].provider;
let email = req.user.email;
let firstName = req.user.name.split(' ').slice(0, -1).join(' ');
let lastName = req.user.name.split(' ').slice(-1).join(' ');
let pictureUrl = req.user.picture;
let profileToSafe = new Profile({
uuid: uuid,
provider: provider,
email: email,
firstName: firstName,
lastName: lastName
});
const profile = Profile.findOne({ uuid });
if (profile !== null) {
profileToSafe.save();
}
res.status(200).send('successful operation');
}
I checked the DB and the document has been stored there.
But I cannot read it.
const getProfile = (req, res) => {
let uuid = req.user.identities[0].id;
Profile.findOne({ uuid: uuid }), function (obj) { console.log(obj) }, function (err) { console.log(err) };
res.status(200).send('successful operation');
}
There is simply no console log output. Not even a null or an error.
I did as mentioned here also I tried to console log findOne function but it returns kind of the whole database, including the authentication data.

You have close the parameter list to the findOne method too early in your second snippet.
Profile.findOne({ uuid: uuid }), function (obj) { console.log(obj) }, function (err) { console.log(err) };
should be
Profile.findOne({ uuid: uuid }, function (obj) { console.log(obj) }, function (err) { console.log(err) });

Related

throw new error_1.MongoInvalidArgumentError('Update document requires atomic operators');

I'm getting (throw new error_1.MongoInvalidArgumentError('Update document requires atomic operators'); )
this type of error
Here is the full code for put endpoint:
app.put('/todo/:id', async (req, res) =>
{
const id = req.params.id; const data = req.body;
console.log(data);
const filter = { _id: ObjectId(id) };
const options = { upsert: true };
const updateDoc = { $set: { name: data.name, message: data.message, }, };
const result = await dataCollections.updateOne(filter, options, updateDoc);
res.send(result);
});
You are sending the parameters in the wrong order, update document comes before options, try this:
const result = await dataCollections.updateOne(filter, updateDoc, options);

How to update only specific field in object within an array Mongodb

Expense Tracker application : Nodejs, Mongodb
Trying to Create a function that will update only the passed fields from request inside an array of objects
Database Schema
const updateExpense = async (req, res) => {
try {
let db = mongo.getDb()
let { macro, micro, amount, note } = req.body;
let { username, id } = req.query
let expense = await db.collection("Expense").updateOne({ username: username, "expenses.expense_id": ObjectId(id) }, { $set: {
"expenses.$.macro": macro,
"expenses.$.micro": micro,
"expenses.$.amount": amount,
"expenses.$.note": note }
});
res.status(200).json({
message: "Expense Updated",
expense: expense
});
} catch (err) {
res.status(500).json({
message: err.message
});
}
}
The above function is replacing all other fields with null
If the user is passing only the micro field, then the other fields should remain the same and only the micro field should change and other fields should not change.
Need A MongoDB Query which will only change what is required based on the data passed in req
I think you must first fetch from the database with findOne then update that fields set in req.body, something like this:
const updateExpense = async (req, res) => {
try {
let db = mongo.getDb()
let { macro, micro, amount, note } = req.body;
let { username, id } = req.query
let expense = await db.collection("Expense").findOne({ username: username });
let special_ex = expense.expenses.find(ex => ex.expense_id === ObjectId(id);
special_ex.macro = macro ? macro : special_ex.macro;
special_ex.micro = micro ? micro : special_ex.micro;
/*
and so on ...
*/
await expense.update();
res.status(200).json({
message: "Expense Updated",
expense: expense
});
} catch (err) {
res.status(500).json({
message: err.message
});
}
}

TypeError: newUser.find is not a function

I am very new to the MERN stack and I would like some help figuring out this error. I'm trying to check if an email is already in the database upon creating a new user. Can anyone tell me why I am getting this error?
The model and scheme
//schema
const Schema = mongoose.Schema;
const VerificationSchema = new Schema({
FullName: String,
email: String,
password: String,
date: Date,
isVerified: Boolean,
});
// Model
const User = mongoose.model("Users", VerificationSchema);
module.exports = User;
The Api
const express = require("express");
const router = express.Router();
const User = require("../Models/User");
router.get("/VerifyEmail", (req, res) => {
console.log("Body:", req.body);
const data = req.body;
const newUser = new User();
newUser.find({ email: data.email }, function (err, newUser) {
if (err) console.log(err);
if (newUser) {
console.log("ErrorMessage: This email already exists");
} else {
console.log("This email is valid");
}
});
res.json({
msg: "We received your data!!!",
});
});
module.exports = router;
The api caller using axios
const isEmailValid = (value) => {
const info = {
email: value,
};
axios({
url: "http://localhost:3001/api/VerifyEmail",
method: "get",
data: info,
})
.then(() => {
console.log("Data has been sent");
console.log(info);
})
.catch(() => {
console.log("Internal server error");
});
};
if you have body in your request, change the type of request to POST...
after that for use find don't need to create a instance of model, use find with Model
router.get("/VerifyEmail", (req, res) => {
console.log("Body:", req.body);
const data = req.body;
User.find({ email: data.email }, function (err, newUser) {
if (err) console.log(err);
if (newUser) {
console.log("ErrorMessage: This email already exists");
} else {
console.log("This email is valid");
}
});
res.json({
msg: "We received your data!!!",
});
});
I prefer to use async/await and don't use Uppercase world for routing check the article: like this
router.post("/verify-email", async (req, res) => {
try {
let { email } = req.body;
let newUser = await User.findOne({ email });
if (newUser) {
console.log("ErrorMessage: This email already exists");
} else {
console.log("This email is valid");
}
} catch (error) {
res.json({
msg: "somthing went wrong",
});
}
res.json({
msg: "We received your data!!!",
});
});
The proper way to query a Model is like so:
const User = mongoose.model('Users');
User.find({<query>}, function (err, newUser) {...
So you need to get the model into a variable (in this case User) and then run the find function directly against it, as opposed to running it against an object you instantiate from it. So this is incorrect:
const newUser = new User();
newUser.find(...
So assuming all your files and modules are linked up correctly, this should work:
const User = require("../Models/User");
User.find({<query>}, function (err, newUser) {...
The problem wasn't actually the mongoose function but I needed to parse the object being sent.
let { email } = JSON.parse(req.body);
Before parsing the object looked like {"email" : "something#gmail.com"}
and after parsing the object looked like {email: 'something#gmail.com'}
I also changed the request from 'get' to 'post' and instead of creating a new instance of the model I simply used User.find() instead of newUser.find()

Pass the results of the query to the outside variable

I am new to node.js and i am trying to create the reset password module for my app. I got stuck on a problem where I wanted to access the result outside of a query.
router.post('/forgot',(req,res)=>{
const db = require('../db.js');
if (req.body.email !== undefined) {
var emailAddress = req.body.email;
// TODO: Using email, find user from your database.
db.query('SELECT * FROM users WHERE email = ?',[emailAddress],(err,results,fields)=>{
if(err){
console.log('Error in pulling the information of the user from the database');
}
var userid = results[0].id;
console.log(userid);
});
var payload = {
id: userid, // User ID from database
email: emailAddress
};
console.log(payload);
} else {
res.send('Email address is missing.');
}
});
I want to get the value of userid which i got from my database and pass it to my outside variable payload and store it in the
id: userid
I did my research on other similar question but was not clear on this topic so any help will be highly appreciated. Thankyou
You're using a callback function here to get the result of your query, what this means is after the query is run it will go ahead and go through the function in the parameter the (err, results, fields) => { ... }, so you could either build your payload inside that callback function, where you would already have the userid on results[0].id or call another function inside that callback with the userid as a parameter.
Something like this
router.post('/forgot', (req, res) => {
const db = require('../db.js');
if (req.body.email !== undefined) {
var emailAddress = req.body.email;
// TODO: Using email, find user from your database.
db.query('SELECT * FROM users WHERE email = ?', [emailAddress], (err, results, fields) => {
if (err) {
console.log('Error in pulling the information of the user from the database');
}
var userid = results[0].id;
console.log(userid);
buildPayload(userid, emailAddress)
});
} else {
res.send('Email address is missing.');
}
});
buildPayload(userId, emailAddress) {
var payload = {
id: userId, // User ID from database
email: emailAddress
};
console.log(payload);
// whatever else you need to do
}

(mongoose) put method does not work

I am creating web API using mongoose.
POST and GET work, but I have no idea how to implement PUT method in mongoose.
Here is what I created:
board.js
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const config = require('../config/database');
const BoardSchema = mongoose.Schema({
_id: {
type: String
},
position: {
type: [String]
}
});
const Board = module.exports = mongoose.model('boards', BoardSchema);
module.exports.getBoardById = function (id, callback)
{
Board.findById(id, callback);
}
module.exports.addBoard = function (newBoard, callback)
{
newBoard.save(callback);
}
module.exports.updateBoard = function (newBoard, callback)
{
newBoard.save(callback);
}
users.js
router.put('/board/:id', (req, res, next) =>
{
let newBoard = new Board({
_id: req.params.id,
position: req.body.position
});
Board.updateBoard(newBoard, (err, board) =>
{
if (err)
{
res.json({ newBoard: newBoard, success: false, msg: "Failed to update board" });
}
else
{
res.json({ newBoard: newBoard, success: true, msg: "Board added" });
}
});
});;
Here, in the board.js, I created methods for adding a new board and updating to existing board. .addBoard is working correctly and am able to test it using Postman. But, .updateBoard adds the data when the data does not exist, but does not update any data and returns false as response (just like POST does). Is there any way I can make the PUT method works?
Thank you!
Please let me know if this works for you! I want to introduce you to http://mongoosejs.com/docs/api.html#findbyidandupdate_findByIdAndUpdate
router.put('/board/:id', (req, res) => {
const {id: _id} = req.params // Assigning id to _id which is a es6 feature. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
const {position} = req.body
const newBoard = {
_id,
position
}
Board.findByIdAndUpdate(
_id,
newBoard,
(err, updatedBoard) => {
if (err) {
res.json({
newBoard,
success: false,
msg: 'Failed to update board'
})
} else {
res.json({newBoard, success: true, msg: 'Board added'})
}
}
)
})
why are you using save method while updating?
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const config = require('../config/database');
const BoardSchema = mongoose.Schema({
_id: {
type: String
},
position: {
type: [String]
}
});
const Board = module.exports = mongoose.model('boards', BoardSchema);
module.exports.getBoardById = function (id, callback)
{
Board.findById(id, callback);
}
module.exports.addBoard = function (newBoard, callback)
{
newBoard.save(callback);
}
module.exports.updateBoard = function (condition, update, callback)
{
Board.update(condition,update,callback);
}
in controller
router.put('/board/:id', (req, res, next) =>
{
let newBoard = new Board({
_id: req.params.id,
position: req.body.position
});
Board.updateBoard({ _id: req.params.id } ,newBoard, (err, board) =>
{
if (err)
{
res.json({ newBoard: newBoard, success: false, msg: "Failed to update board" });
}
else
{
res.json({ newBoard: newBoard, success: true, msg: "Board added" });
}
});
});
try this.
As you are using req.body i think you are trying to call a put request from a form (sometimes happens with AJAX requests also). For doing that use method-overide. And set the xhr header as given in the documentation. This will surely work.

Resources