I have two collection update calls inside of a Method, which don't seem to be running at all.
Meteor.users.update({ _id: Meteor.user()._id }, { $push: { 'stars.teamStars': team.name } });
Teams.update({ _id: team._id }, { $inc: { stars: 1 } });
When I try to run the Teams update in the console it works correctly.
Although, when I try to run the users update in the console I receive update failed: Access denied.
I'm quite confused, as I have very similar update calls in other parts of my app, and they run perfectly.
Edit:
Should my Meteor.methods be located in /server?
Check your code for Meteor.users.allow rules. You have removed the insecure package using (meteor remove insecure). This means you have to explicitly give meteor an allow rule for example:
Meteor.users.allow({
update: function (userId, doc, fields, modifier) {
// can only change your own documents
return doc.owner === userId;
}
});
Related
I'm trying to check that an update command accomplished but when I check for the nModified I'm getting 0 although I do see that the field value changes from one value to another (not kept the same value).
static async updateProfile(username, profileData) {
const usersCollection = db.dbConnection.collection(dbConfig.collectionNames.users);
const updateRes = await usersCollection.update({email: username},
{"$set": {
firstName: profileData.firstName,
lastName: profileData.lastName,
payment: profileData.payment,
}
});
return updateRes.result.nModified > 0;
}
Is there another way to verify the update?
One of the way by findAndModify method:
You can easily compare whole new object and verify each key.
db.getCollection('usertests').findAndModify({
query: {"email":"xxx#xxx.com"},
update: {name: "HHH", "email":"xxx#xxx.com"},
new: true
})
new: true is responsible to return whole updated document. If fail to update it will return null.
Take care here to pass the whole document while update.
update() only return a number of the documents that were successfully updated. So, your logic to check if updated successfully or not is also valid.
I'm working on a CRUD application with Node, Mongo & Monk.
I'd like to find a record by username, and then update it.
But I'm unable to find a record, this code isn't working:
// GET User Profile
router.get('/userprofile', function(request,response){
var db = request.db;
var userName = request.body.username;
var collection = db.get('usercollection');
collection.findOne({
"username": userName
},{},function(e,user){
response.render('userprofile', {
"user": user
});
});
});
The "findOne" method doesn't return anything, and the "user" object ends up empty.
Remove the middle empty object from the signature for the findOne() method signature for the query to work:
Note: The way you are getting the userName is for when the request method is a POST, here you are doing a GET so you need to use the request.query property. More details here
var userName = request.query.username;
collection.findOne({"username": userName}, function(e,user){
response.render('userprofile', { "user": user });
});
If you want to update then you can use the update() method, suppose you want to update the username field to change it to 'foo', the following stub shows how you can do the update:
var u = collection.update({ "username": userName }, { "$set": { username: 'foo' } });
u.complete(function (err, result) {
console.log(err); // should be null
console.log(result); // logs the write result
});
Ok, I found out the problem.
Chridam's code was correct, but I also needed to change my form from a GET to a POST. Once I did that, the form POSTed and mongo could see request.body.username (it was null before) and look up my user using Chridam's code.
After reading Chridam's revised answer, was also able to get it to work with GET.
Now working on the update code..
I have a meteor application which upon startup seeds a mongo db document:
Meteor.startup(function () {
Dynamics.remove({});
Dynamics.insert({ name : "voteTimer", time : 0 });
Dynamics.insert({ name : "winningWord", content : "" });
});
These are called in a React component eg:
getMeteorData() {
return {
winningWord: Dynamics.findOne({name: "winningWord"}).content
}
},
On my local machine this works fine. Once deployed via meteor deploy however, the app crashes:
Cannot read property 'content' of undefined
This indicates that there are no documents in the Dynamics collection. Even stranger, I am still able to access these variable in the chrome dev console.
Even if you start inserting items on startup, those inserts are asynchronous and your component's getMeteorData probably still tries to fetch your document before it is inserted. Since getMeteorData is reactive (I think), you simply need to check for your findOne to return a proper document and it should work as soon as the document is ready:
getMeteorData() {
var dynamic = Dynamics.findOne({name: "winningWord"});
if (dynamic) {
return {
winningWord: dynamic.content
}
}
return {winningWord:""}; // whatever
},
Does Moongoose 3.8.8 (the lastest version) support $position (http://docs.mongodb.org/manual/reference/operator/update/position/) operator from MongoDB 2.6.0?
In the following code example the new elements is inserted in the end of the array userActivity.activities:
model:
var userActivity = new schema({
userId: {type:String, required:true, unique:true},
activities: [activity]
});
var activity = new schema({
act: {type: Number, required:true},
});
query:
var activity = { act: 1 };
model.userActivity.update(
{ _id: dbact._id },
{ $push: { activities: {
$each: [ activity ],
$position: 0
}
}
},
function (err, numAffected) {
if (!err) {
// do something
}
});
This actually doesn't matter and never matters for any "framework" implementation and I do not mind explaining why.
Every single "framework" ( such as Mongoose, Mongoid, Doctrine, MongoEngine, etc, etc, etc ) are all basically built upon a basic "driver" implementation that has in most cases been developedby the MongoDB staff themselves. So the basic functionality is always ther even if you need to "delve" down to a level in order to use those "native" methods.
So here would be the native usage example in this case:
List.collection.update(
{},
{ "$push": {
"list": {
"$each": [ 1, 2, 3 ],
"$position": 0 }
}
},function(err,NumAffected) {
console.log("done");
});
Note the "collection" method used from the model, which is getting the "raw" collection details from the driver. So you are using it's method and not some "wrapped" method that may be doing additional processing.
The next and most basic reason is if you cannot find the method and application of the operators that you need the here is a simple fact.
Every single operation as used by the methods in every framework and basic driver method is essentially a call to the "runCommand" method in the basic API. So since that basic call is available everywhere ( in some form or another, because it has to be ), then you can do everything that you find advertised on the MongoDB site with every language implementation on any framework.
But the short call to your particular request is, since this is not actually a method call but is simply part of the BSON arguments as passed in, then of course there is no restriction by a particular language driver to actually use this.
So you can use these new argument without of course updating to the most recent version. But you probably will get some nice methods to do so if you actually do.
Yes, you should be able to use it directly as Mongoose will pass through the update clause:
Model.update(
query, /* match the document */
{ $push:
{ yourArrayField:
{
$each: [ 1, 2, 3 ],
$position: 0
}
}
}, function (err, res) { /* callback */ });
The above would insert the values 1, 2, 3 at the front of the array named yourArrayField.
As it's just a pass-through, you'll need to make sure it works with the server version that you're connecting the client to.
I've create a test database like this:
Test.insert({_id: "XJAGgP3whnNd2HZec"}) ;
Test.insert({_id: "user1"} );
Test.insert({_id: "user8"} );
Test.insert({_id: "user5"}) ;
Test.update({_id: "XJAGgP3whnNd2HZec"}, {
$push: { users:{name8: "test5"}} });
Test.update({_id: "user5"}, {
$push: { users:{name8: "test5"}} });
Test.update({_id: "user8"}, {
$push: { users:{name9: "test5"}} });
Test.update({_id: "user1"}, {
$push: { users:{name9: "test4"}} }) ;
From meteor mongo I can search for results. For example:
> db.test.find({'users.name9': "test4"}).count()
1
> db.test.find({'users.name9': {$ne: "test4"}}).count()
3
>
If I put the same query inside Meteor. For example:
console.log(Test.find({'users.name9': { $ne: "test4" } }) ),
Meteor returns a collection object with all the entries.
Am I missing something obvious here?
I realised the logic in my original question wasn't quite right.
I raised a ticket which has now been fixed:
Clearer in this ticket: https://github.com/meteor/meteor/issues/1451
I just tried that too, and it works fine for me. I don't know what your problem is, but I'd try meteor reset (which refreshes your database deleting everything and starting over), and if that doesn't work, I'd try creating a new project. You can copy your code files over to the new project, if you don't want to write them again.