Mongoose get current data even it's not valid with the model - node.js

I changed two properties in my User.model:
address: [
{
street: String,
number: Number,
city: String,
country: String
}],
phone: [
{
landLine: String,
mobilePhone: String
}]
to only a object:
address:{
street: String,
number: Number,
city: String,
country: String
},
phone:{
landLine: String,
mobilePhone: String
}
However, there are still some users which holds an array on it. So I created an script to update those users, but when using User.find({}), the phone and address property are undefined. I guess that is because that there are not valid with the current model.
Since user.address and user.phone are both undefined, the data object will only contain 2 empty objects for phone and address which results in users without address and phone.
This is the code which I use for getting and updating the users:
function updateUser(id, data){
return new Promise( (resolve, reject) =>{
User.findByIdAndUpdate(
{_id: id},
{
$set: data
}
).exec( (err, res) => {
if(err) return reject(err);
return resolve();
})
})
}
module.exports.updateUsers = (req, res) => {
Users.find({}).exec( (err, users) => {
//For testing, update only 1 user
//User.find({username: 'some#emailaddress'}).exec( (err, users) => {
if(err) return res.status(500).json({message: "Error getting users"})
return blueBird.mapSeries(users, (user) => {
let data = {
address: {},
phone: {}
}
if(user.address && user.address.length > 0){
data.address = user.address[0];
}
if(user.phone && user.phone.length > 0){
data.phone = user.phone[0];
}
return updateUser(user._id, data);
})
.then(() => {
return res.status(200).json({ status: true, message: "Users are updated" });
})
.catch((e) => {
return res.status(500).json({ status: false, message: "Some error occured while code execute.", error: e });
})
})
}
How can I get the current data from the model without validation from the model?

I think you should revert your address and phone Schema, and create temporary fields (like tmpAddress and tmpPhone) with you new Object schema like this :
address: [{
street: String,
number: Number,
city: String,
country: String
}],
phone: [{
landLine: String,
mobilePhone: String
}],
tmpAddress: {
street: String,
number: Number,
city: String,
country: String
},
tmpPhone: {
landLine: String,
mobilePhone: String
}
And then you save your new fields like this :
data.tmpAddress = user.address[0];
data.tmpPhone = user.phone[0];
Once this is done, you can rewrite your address and phone Fields with Object Schema, copy tmpAddress -> address and tmpPhone -> phone, and delete tmpAddress and tmpPhone fields.
Hope it helps.

Related

Why is the create() function in node js not creating the data in the mongoDB?

I basically wrote a code to check if the data is existing or not in the mongoDB and if it is then I'm trying to create a new document and if it is then I'm basically updating the same document
this is my controller code
Controller.js
try {
console.log(req.body)
let data = await IITSchema.findOne({ Email })
console.log(data)
if (data) {
const updateFormData = await IITSchema.findOneAndUpdate(
{ Email },
{
PhoneNumber,
YearofGrad: YearofGrad,
FullName,
Evidence,
CollegeName: CollegeName,
user: SaveUserData._id,
City: City,
GraduationDegree: GraduationDegree,
Department: Department,
placement_time: placement_time,
targeted_companies: targeted_companies,
interests,
In_what_areas_do_you_need_our_help,
Others,
}
);
return res.status(200).json({ message: "update", data: updateFormData });
} else {
// if (!SaveFormData) {
const newformdata = new IITSchema({
})
const newFormData = await IITSchema.create({
Email,
password: hashedPassword,
PhoneNumber,
YearofGrad: YearofGrad,
FullName,
Evidence,
CollegeName: CollegeName,
// user: user._id,
City: City,
GraduationDegree: GraduationDegree,
Department: Department,
placement_time: placement_time,
targeted_companies: targeted_companies,
interests,
In_what_areas_do_you_need_our_help,
Others,
});
return res.status(200).json({ message: "create", data: newFormData });
}
} catch {
(err) => {
console.log("error from New Step Form", err);
res.json({ error: err });
};
}
this is my Model
const mongoose = require("mongoose");
const IITSchema = new mongoose.Schema({
FullName: String,
Email: String,
interests: { type: [String] },
CollegeName: String,
YearofGrad: String,
password: String,
Evidence: Boolean,
Department: String,
GraduationDegree: String,
In_what_areas_do_you_need_our_help: { type: [String] },
City: String,
placement_time: String,
targeted_companies: String,
PhoneNumber: String,
Others: String,
referral: { type: String, default: null },
});
module.exports = mongoose.model("iitbombay", IITSchema);
and this is the req.body that I'm getting from the front end
{
FullName: 'Mohammed Khan',
Email: 'aven.farhan#gmail.com',
password: 'asdfsadfsd',
Evidence: true,
PhoneNumber: '+919515876470',
CollegeName: ' GURU PRAKASH B.ED. COLLEGE , Kaimur (Bhabua), Bihar',
YearofGrad: 2023,
GraduationDegree: 'Bsc',
Department: 'CSE',
City: 'Adoni',
In_what_areas_do_you_need_our_help: [ 'Complete Placement Preparation' ],
targeted_companies: 'FAANG (Facebook, Amazon, Apple, Netflix and Google)',
placement_time: 'Less than 1 month',
interests: [ 'Data Science / Analytics' ]
}
this is the code that I'm using to send the data to the backend i.e node js and mongodb
await fetch(BASE_URL + "/iitbfform", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newData),
})
.then((res) => res.json())
.then((data) => {
console.log("Response from firstForm", data);
});
the code is completely fine but the document is not getting saved
it would mean alot if some can point out the error that I'm doing over here

Find ObjectId of an element inside an array of docs, that is inside a model with Mongoose

I have this model:
const userSchema = new Schema({
email: {
type: String,
required: true,
unique: true
},
firstname: String,
lastname: String,
password: {
type: String,
required: true
},
activities: [{
description: {
type: String,
required: true
},
status: String,
from: Date,
to: Date
}]
}, { timestamps: true })
After I get the user with User.findById(), how can I get the ObjectId of an activity inside the activities array so I can perform (for example) delete and update operations?
EDIT 1
I can see every ObjectId with console.log() or in my GUI because MongoDB creates an ObjectId for every element inside the array even if I don't specify the field _id for each element. Here's a sample:
USER ACTIVITIES [
{
_id: 603765c7bb1d1c24cc7f80ff,
description: 'Complete the project',
status: 'pending',
from: 2021-02-25T08:54:31.719Z,
to: 2021-02-25T08:54:31.719Z
},
{
_id: 60377672bb1d1c24cc7f8100,
description: 'Figure out how to get the ObjectId',
status: 'pending',
from: 2021-02-25T10:05:38.144Z,
to: 2021-02-25T10:05:38.144Z
}
]
I'd like to access this _id so I can perform operations on a single activity
I've just found a solution. In my routes file I've added one more parameter in the endpoint's path (the element ID) so I can access it via req.params. Then everything is simple. Here's a sample:
Route
router.delete('/activities/:id/:activityId', userController.deleteActivity);
The logic
exports.deleteActivity = async (req, res, next) => {
try {
const id = req.params.id;
const user = await User.findById(id);
if (user) {
const activityId = req.params.activityId;
await user.activities.pull(activityId);
await user.save();
console.log("ACTIVITY REMOVED! YOUR ACTIVITIES", user.activities);
return res.status(200).json({ activities: user.activities });
}
return res.status(400).json({ message: "USER NOT FOUND!" });
} catch (error) {
console.log(error);
res.status(500).json({ error });
}
};

Mongoose removed some data from the model.find and model.FindOne response

I'm building an Express/Node application and I'm trying build a login controller. When the request comes through to /login, I am able to find the user details in my Mongo collection with Mongoose' model.findOne, but the problem is that what the function returns is not all that is in the mongo document.
Querying the data through Robo 3T returns all the information
Here is my model
{
firstname: String,
surname: String,
fullname: String,
firthDate: Date,
identityType: String,
identityNumber: String,
address: {
residential: Object,
business: Object
},
contact: {
email: String,
cellphone: String,
home: String,
business: String,
fax: String
},
compliance: {
type: String,
value: String
},
account: {
type: String,
username: String,
password: String,
masala: String
},
created: Date,
updated: Date
}
Here is my controller:
user.findOne({"account.username": username}, (err, doc) => {
if (!err) {
// found user. Compare passwords and return JWT;
console.log(doc);
bcrypt.compare(password, doc.account.password, (err, isValid) => {
// I get an error here : Cannot read property password of undefined.
if (!err) {
if (isValid) {
// generate jwt and send back to user;
}
} else {
// invalid password provided;
}
});
} else {
}
});
I get an error: Cannot read property "password of undefined.
And this is the response that is in "doc" :
{
firstname: "hello",
surname: "world",
fullname: "hello world",
firthDate: "01 January 1970",
identityType: "idnumber",
identityNumber: "12345",
address: {
residential: {},
business: {}
},
contact: {
email: "",
cellphone: "",
home: "",
business: "",
fax: ""
},
compliance: {
type: "",
value: ""
}
}
It looks like the "doc.account" data is not returned as part of the response from the findOne function. I don't know why because I am using the data in the "doc.account" to search in the first place.
Your account schema is wrong.
For nested objects, it should be like this.
acount:{
username: {type:String},
password: {type:String},
}
Now this will be considered an object with properties username and password

Nested array value comparison with another array value in mongoose using nodejs

How can I get addedproducts array elements where productids' of addedproducts array match with every id in productids' array of invitationfrom array(for a particular user email) in the below structure?
var UserSchema = new Schema(
{ email:
{ type: String,
unique: true,
required: true
},
addedproducts:[ {
name: String,
productid:String,
producttype:String
} ],
invitationfrom : [ {
fromemail: String,
productid:[String]
}]
}, {collection: 'user-data-db'});
Try this one
User.find({'addedproducts.productid': "123456"}, {'invitationfrom.productid': "123456"})
.exec(function (err, user) {
if (err) {
return res.status(500).json({message: err});
}
if (!user) {
return res.status(404).json({message: 'No Match Found'});
} else {
return res.status(200).json(user);
}
});

Update of object in MongoDB with node.js

So I have a db model defined in my server.js file which will be used for a POST :
var department = mongoose.model('department', {
departmentName: String,
rooms: [{
roomNumber: String,
width: Number,
height: Number,
posX: Number,
posY: Number,
sanitary: Boolean,
childcareArea: Boolean,
lounge: Boolean,
patient: {
patientnr: Number,
firstname: String,
lastname: String,
reasonOfHospitalization: String,
dateOfHospitalization: String,
expectedDateOfDischarge: String,
vegetarian: Boolean,
needsHelp: Boolean,
comments: String,
department: String,
roomNumber: String,
nextTreatment: {
type: String,
shortDescription: String,
timestamp: String
}
}
}]
});
Now what I want to achieve is that my post call updates the patient object.
public postPatient(patient: Patient) {
var headers = new Headers();
headers.append('Content-Type', 'application/json; charset=utf-/8');
let url ='http://localhost:8080/api/departments/patients/' + patient.patientnr;
this.http.post(url, JSON.stringify(patient), headers)
.map(res => res.json());
}
This is how I handle my post, but it updates nothing in my database...
app.post('/api/departments/patients/:id', function(req, res) {
var patient = req.body.patient;
department.findOneAndUpdate(
{ "rooms.patient.patientnr": parseInt(req.params.id) },
{
"rooms": {
"$elemMatch": {
"patient.patientnr": parseInt(req.params.id)
}
}
}, {
"$set": {
"rooms.patient": patient
}
}, {
new : true
},
function (err, dept) {
if (err){
console.log(err.stack);
return res.send(err);
}
return res.json({
data: department,
status: 'success'
});
});
});
Something like this should work for you. Finds and replace the patient for the selected room.
department.findOneAndUpdate(
{ "rooms.patient.patientnr": parseInt(req.params.id) },
{ "$set": {"rooms.$.patient": patient}},
{new : true}
....
)

Resources