Can't update values in mongodb database - javascript

Username doesn't get updated after running this. I also tried UpdateOne and it didn't work as well. The code was supposed to update an array but I tried updating the username to make it easier to track down the problem.
const mongoose = require('mongoose');
const schema = mongoose.Schema;
const userSchema = new schema({
Username:{
type: String,
required: true
},
Password:{
type: String,
required: true
},
Cart: Array
});
const User = mongoose.model('User', userSchema);
module.exports = User;
.
app.post('/putbox', (req, res) => {
var query = { Username: user };
var newvalues = { $push: { Cart: "Boxing" } };
try{
User.find(query).then((d)=>{
var values = d[0].Cart;
values.push("boxing")
User.findByIdAndUpdate(d._id, {Username: "test1"})
});
} catch(err) {
console.log(err);
}
res.redirect('/boxing');
});

I believe the syntax is not correct. The first element of updateOne searches for matches to update. You are just passing d._id which is not the same as the _id key in your db structure. Try this one
User.updateOne({ _id: d._id }, {Username: "test1"})

Related

How to insert data into MongoDB collection?

I'm using NodeJS with Mongoose. I've two tables into db.js:
const mongoose = require('mongoose')
const UserSchema = new mongoose.Schema(
{
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true }
},
{ collection: 'users' }
)
const model = mongoose.model('UserSchema', UserSchema)
const AccountSchema = new mongoose.Schema(
{
username: { type: mongoose.Schema.Types.ObjectId, required: true, ref: 'hahaha' },
balance: { type: Number, required: true }
},
{ collection: 'accounts' }
)
module.exports.UserSchema = model
module.exports.AccountSchema = model
As you can see the first collection contains users (username, email, password). The second collection represents a bank account, related to a specific user. So, it has two fields: user (foreign key) and balance ($100, i.e.). First question: is my code correct to accomplish this task?
Second question: how can I insert data into the AccountSchema?
I obviously want to insert data only if the user exists into Userschema. I think that this doesn't work:
const Schema = require('./model/db')
app.post('/api/addaccount', async (req, res) => {
const { username, balance } = req.body
try {
const response = await Schema.AccountSchema.create({
username,
balance
})
console.log('User account successfully: ', response)
res.json({status : "ok"})
} catch (error) {
throw error
}
})
How can I do this?
This won't work. You've to query the User model first to check if any user exists with this username. If yes, you'll continue to store data in the Account model, if not you'll return a response something like user doesn't exist

How to find a document in mongoose by child property?

I have this Person and User models in my project:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const schema = new Schema({
name: {
type: String,
required: true
}
});
module.exports = mongoose.model('Person', schema);
and
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const schema = new Schema({
person: {
type: mongoose.SchemaTypes.ObjectId,
ref: 'Person',
required: true
},
email: {
type: String,
required: true
}
});
module.exports = mongoose.model('User', schema);
As we can see, a User has a reference to Person. I'm trying to find one User by either his email or by name of his Person. I tried many different approaches, like this:
exports.getUserByPersonNameOrEmail = async (uservalue) => {
var user = await User.findOne({
$or: [
{"person.name": uservalue},
{email: uservalue}
]
});
return user;
};
I also read about using the $elemMatch command, but it seems that it is used for documents with an array of children, instead of a specific child.
You would have to use mongoose populate and its match step during populate:
var user = await User.findOne({}).populate({
path: 'person',
match: { name: uservalue },
select: 'name -_id'
}).exec()
You can read more about it here. The idea basically is that you have to populate the actual references to person in your use model in order to query them. match applies a filter while they are being populated etc.

Mongoose - Model.deleteOne() is deleting the entire collection instead of a single document

I have a User model that contains an array of customers. I want to delete a specific customer based on the customer _id. From what I've read in the Mongoose docs, I should use Model.deleteOne to delete a single document.
Here is my attempt
User Schema (it's been shortened for brevity):
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
username: {
type: String,
default: ''
},
password: {
type: String,
default: '',
},
registerDate: {
type: Date,
default: Date.now()
},
customer: [{
name: {
type: String,
default: '',
},
email: {
type: String,
default: 'No email name found'
},
fleet: [{
unitNumber: {
type: String,
default: 'N/A',
}
}]
}]
});
module.exports = mongoose.model('User', UserSchema);
Here is a look at the route and controller:
const express = require('express');
const router = express.Router();
const customer_controller = require('../../controllers/customers');
router.delete('/customers/:custid', customer_controller.customer_remove);
module.exports = router;
And finally the controller:
exports.customer_remove = (req, res) => {
const { params } = req;
const { custid } = params;
User.deleteOne({ 'customer._id': custid }, (err) => {
if (err)
throw err;
else
console.log(custid, 'is deleted');
});
};
From what I thought, User.deleteOne({ 'customer.id': custid }) would find the customer _id matching the custid that is passed in via the req.params. When I test this route in Postman, it deletes the entire User collection that the customer is found in, instead of just deleting the customer. Can I get a nudge in the right direction? I feel like I am close here (or not lol).
deleteOne operates at the document level, so your code will delete the first User document that contains a customer element with a matching _id.
Instead, you want update the user document(s) to remove a specific element from the customer array field using $pull. To remove the customer from all users:
User.updateMany({}, { $pull: { customer: { _id: custid } } }, (err) => { ...
Using Mongoose you can do this:
model.findOneAndUpdate({ 'customer._id': custid }, {$pull: { $pull: {
customer: { _id: custid } }}, {new: true}).lean();
Removing subdocs.
Each sub document has an _id by default. Mongoose document arrays have a special id method for searching a document array to find a document with a given _id.
Visit: https://mongoosejs.com/docs/subdocs.html
parent.children.id(_id).remove();
Use async-await, may be that will work.
exports.customer_remove = async (req, res) => {
const { params } = req;
const { custid } = params;
try {
await User.deleteOne({ 'customer._id': custid });
console.log(custid, 'is deleted');
} catch (err) {
throw err;
}
};

Mongoose + Mongodb User.update not working

What I am trying to do is create a new collection, and push that collection into a specific User.collections array. I have read many stackoverflow posts and they all say to use either User.update() or User.findOneAndUpdate(). I am have no luck with either. I can create a Collection and that is saved to mongo so I know I am indeed accessing the db. Here is my code, if any of you can help I would appreciate it.
User Schema
const mongoose = require('mongoose');
const { Schema } = mongoose;
const userSchema = new Schema({
googleID: String,
givenName: String,
familyName: String,
collections: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "collection"
}
]
});
mongoose.model('users', userSchema);
Collection Schema:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const collectionSchema = new Schema({
type: String,
name: String,
gamesCollected: [
{
id: Number
}
]
});
mongoose.model('collection', collectionSchema);
And my route:
router.get('/get_collection', (req, res) => {
const collection = new Collection({
type: 'SNES',
name: 'First SNES Collection',
gamesCollected: [{ id: 5353 }]
}).save();
User.update({googleID: req.user.googleID}, {$push: {collections: collection}});
});
Save is not a synchronous operation but asynchronous so you need to use the promise it returns and handle it and once it is complete then update the user model. Something among these lines:
router.get('/get_collection', async (req, res) => {
let collection = new Collection({
type: 'SNES',
name: 'First SNES Collection',
gamesCollected: [{ id: 5353 }]
})
await collection.save().exec();
await User.update(
{googleID: req.user.googleID},
{$push: {collections: collection._id}}
).exec();
});

Save doesn't save any data

I'm trying to save some data into a local mongodb database.
My schema looks as follows:
const mongoose = require('mongoose');
const userSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: String,
email: String,
passwordHash: String,
registerTimeStamp: { type: Number, default: Date.now() },
usersFollowing: [],
accountStatus: {
isBanned: { type: Boolean, default: false },
reason: { type: String, default: '' }
}
});
module.exports = mongoose.model('User', userSchema);
and the insert Method looks like this:
createUser(name, email, password) {
const passwordHash = "asdf";
const user = new User({
_id: new mongoose.Types.ObjectId(),
name,
email,
passwordHash
});
user.save(console.log("saved"));
}
my problem is, that even though I called the method with the right arguments, and it prints "saved", no data is inserted into the database.
Thanks!
First of all, when you call:
user.save(console.log("saved"));
The console will print "saved" no matter if you get or not an error. So maybe you are getting an error without a proper handler. If you really want to know what is happening with your user instance:
user.save()
.then(() => console.log("saved"))
.catch((error) => console.log(error));
If you want to use callbacks instead of promises:
user.save(function(error) {
if(error) throw error;
console.log("saved");
});
Now, there is an error in your insert method.
Change:
_id: new mongoose.Types.ObjectId(),
With:
_id: new mongoose.Types.ObjectId,
The parenthesis is the problem.
const mongoose = require('mongoose');
const userSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: String,
email: String,
passwordHash: String,
registerTimeStamp: { type: Number, default: Date.now() },
usersFollowing: [],
accountStatus: {
isBanned: { type: Boolean, default: false },
reason: { type: String, default: '' }
}
});
const User = mongoose.model('User', userSchema);
module.exports = User;
module.exports.createUser = function (name, email, password) {
const passwordHash = "asdf";
const user = new User({
_id: new mongoose.Types.ObjectId(),
name,
email,
passwordHash
});
User.save(user , callback);
}
The problem is that you are just logging the message, not saving the user in your database.
In order to do that, first you have to export the user model doing something like this:
const UserModel = mongoose.model('User', userSchema)
module.exports = UserModel
Next, in the same file where you have the createUser method, you import the UserModel. Then in your createUser method, you call the .save method but from your model just imported, sending the just created user:
const UserModel = require('../pathtothefile') //Here you specify the path of the user-model file
createUser(name, email, password) {
const passwordHash = "asdf"
const user = new User({
_id: new mongoose.Types.ObjectId(),
name,
email,
passwordHash
})
return UserModel.save(user)
}

Categories

Resources