Meteor collection2 does not validate on the client side - mongodb

I am using collection2 with meteor to set default values. However when i run the method Meteor.call('commands.insert', {}) on the client, it just sets new document's ID, and only when the result from server comes it replaces the document with the right value. Actually, autoValue function runs on client because when i console.log there it logs (also tried defaultValue), but it does not do anything, does no modifications, nor unique: true is working, any property specified in the schema
server
export const Commands = new Mongo.Collection('commands')
Commands.schema = new SimpleSchema({
designation: {
type: String,
autoValue: function() {
console.log("inssssssssssssssssssseeeeeeeeeeeeeeeeeeeeeeert")
if (this.isInsert) {
return "Untitled"
}
},
unique: true
},
name: {
type: String,
autoValue: function() {
if (this.isInsert) {
return ""
}
},
optional: true
},
syntax: {
type: String,
autoValue: function() {
if (this.isInsert) {
return ""
}
},
optional: true
},
description: {
type: String,
autoValue: function() {
if (this.isInsert) {
return ""
}
},
optional: true
},
features: {
type: String,
autoValue: function() {
if (this.isInsert) {
return ""
}
},
optional: true},
type: {
type: String,
autoValue: function() {
if (this.isInsert) {
return ""
}
},
optional: true
},
variants: {
type: Array,
autoValue: function() {
if (this.isInsert) {
return []
}
},
},
'variants.$': {type: String}
})
Commands.attachSchema(Commands.schema)
Meteor.methods({
'commands.insert'(command) {
if (!this.userId) {
throw new Meteor.Error('not-authorized')
}
Commands.insert(command)
}
})
client
const setNewHandler = this.props.page.animationFinished ?
this.props.page.editing ?
textEditorData.length ?
() => {
Meteor.call(
'commands.update',
textEditorData[0]._id,
{
designation:
this.childComponents[0].editableContentNode.textContent,
name:
this.childComponents[1].editableContentNode.textContent,
syntax:
this.childComponents[2].editableContentNode.textContent,
type:
this.childComponents[3].editableContentNode.textContent,
variants:
this.childComponents[4].editableContentNode.textContent.split("\n"),
description:
this.childComponents[5].editableContentNode.textContent,
features:
this.childComponents[6].editableContentNode.textContent
}
)
} :
null :
() => {
Meteor.call('commands.insert', {})
} :
null

Related

Change field in object in array of object

I have a field achivment with an array of objects. I need to update the field currentPoints in one object that I will find by field name in the array.
Code model of mongoose:
const achive = new Schema(
{
achiveId: ObjectId,
name: { type: String, required: true },
finishedPoints: { type: Number, required: true },
currentPoints: {
type: Number,
default: 0,
set: function (v) {
if (v >= this.finishedPoints) this.isFinished = true;
return v;
}
},
isFinished: { type: Boolean, default: false }
},
{ _id: false }
);
const achivesSchema = new Schema({
userId: ObjectId,
achivement: [achive]
});
Code query:
export async function progressAchive(req, res) {
const value = 3;
try {
const test = await Achives.updateOne(
{
userId: req.user._id,
achivement: { $elemMatch: { name: req.params.nameAchive } }
},
{ $set: { achivement: { currentPoints: value } } },
{ new: true }
);
res.json(test);
} catch (e) {
console.log(e);
}
}
Instead of updating, it removes all objects from the array and leaves them one object with the currentPoint field. How can I update this like I want?
You should use the following for update
const test = await Achives.updateOne(
{
userId: req.user._id,
},
{
$set:{"achivement.$[el].currentPoints": value}
},
{
arrayFilters:[{
"el.name": req.params.nameAchive
}],
new: true
}
);

How can I overwrite the entire document, instead of just updating the fields?

How can I overwrite the entire document, instead of just updating the fields?
Here is the method I use right now but doesn't work:
updateFilmTitle: function(req, res) {
var id = req.params.id;
console.log(id);
filmTitleModel.findByIdAndUpdate(id, req.body, {
overwrite: true
}, {
new: true
}, (error, response) => {
if (error) {
res.json(error);
console.error(error);
return;
}
console.log("filmTitle form has been updated!");
res.json(response);
console.log(response);
});
},
here how my model looks like,
var venueSchema = new Schema({
ticketServiceRequired: { type: Boolean, required: true },
filmSettings: {
type: {
filmContactName: { type: String, required: true },
filmSeatingAmount: { type: Number, required: true },
filmMediaDelivery: { type: Array, required: true },
filmRentalFee: {
price: { type: Number, required: true },
type: { type: String, required: true },
},
}
},
});
new and overwrite both are options, so it should be this:
filmTitleModel.findByIdAndUpdate(id, req.body, {
overwrite : true,
new : true
}, (error, response) => { ... });

updating objects in double nested arrays in a collection

Having this schema:
Task = new SimpleSchema({
_id: {
type: String,
regEx: SimpleSchema.RegEx.Id,
autoValue: function(){ return Random.id(); }
},
title: {
type: String,
label: "Task title",
}
});
Card = new SimpleSchema({
_id: {
type: String,
regEx: SimpleSchema.RegEx.Id,
autoValue: function(){ return Random.id(); }
},
tasks: {
type: [Task],
label: "Card tasks",
optional: true
}
});
ProjectSchema = new SimpleSchema({
name: {
type: String,
label: "Project name"
},
cards: {
type: [Card],
label: "Project cards",
optional: true
}
});
I'm trying to update it with this function, passing the 3 ids and an object with the editted task:
editTask : function(projectId,cardId,taskId,oTask) {
if (! Meteor.userId()) {
throw new Meteor.Error("not-authorized");
}
check(projectId, String);
check(cardId, String);
check(taskId, String);
check(oTask, Object);
Projects.update({
_id: projectId,
cards: {
$elemMatch : {
_id: cardId,
tasks : {
_id : taskId
}
}
}
},
{
$set: {"tasks.$.Task": oTask}
});
}
Error says: when the modifier option is true, validation object must have at least one operator.
As far as I know that error means the $set: {"tasks.$.Task": oTask} it's not pointing correctly.
I've also tried: $set: {"cards.tasks.$.Task": oTask},$set: {"cards.$.tasks": oTask}

Get single attribute in model using Mongoose

I have 2 Schemas : StepSchema, StepRelationshipSchema
var StepSchema = new Schema(
{
name: { type: String, required: true },
description: { type: String, default: '' },
isVisible: { type: Boolean, default: true }
}, options
);
var StepRelationshipSchema = new Schema(
{
workflowId: { type: String, required: true },
stepId: { type: String, required: true },
prevSteps: [ Schema.Types.Mixed ] ,
nextSteps: [ Schema.Types.Mixed ] ,
gotoStep: { type: String, default: '' }
}, options
);
In StepSchema, I want to create a static method to get nextSteps in StepRelationshipSchema.
Can I use this, thank you so much.
StepSchema.statics.getNextSteps = function(workflowId, currStepId) {
return StepRelationship.findOne({
workflowId: workflowId,
stepId: currStepId
}).nextSteps
};
As #JohnnyHK suggested in his comments, findOne() is async thus you need to use a callback function as follows:
// create a query for next stepswith a blogpost _id matching workflowId and currStepId
schema.statics.getNextSteps = function (workflowId, currStepId, callback) {
return this.model('StepRelationship').findOne({
workflowId: workflowId,
stepId: currStepId
}, callback);
}

Validation object must have at least one operator / meteor mongo

I wrote a method to a user's address to a collection. However, i keep getting the error:
When the modifier option is true, validation object must have at least one operator.
Here is my schema:
var Schemas = {};
Schemas.UserAddress = new SimpleSchema({
streetAddress: {
type: String,
max: 100,
optional: false
},
city: {
type: String,
max: 50,
optional: false
},
state: {
type: String,
regEx: /^[a-zA-Z-]{2,25}$/,
optional: false
},
zipCode: {
type: String,
regEx: /^[0-9]{5}$/,
optional: false
}
});
Schemas.User = new SimpleSchema({
emails: {
type: [Object],
optional: false
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email
},
"emails.$.verified": {
type: Boolean
},
createdAt: {
type: Date
},
profile: {
type: Schemas.UserProfile,
optional: false
},
address: {
type: Schemas.UserAddress,
optional: false
},
services: {
type: Object,
optional: true,
blackbox: true
}
});
Meteor.users.attachSchema(Schemas.User);
And here is my addAddress event:
Template.editAddress.events({
'click .addAddress': function(e, tmpl) {
e.preventDefault();
var currentUserId = this._id;
var addressDetails = {
address: {
streetAddress: $('#streetAddress').val(),
city: $('#city').val(),
state: $('#state').val(),
zipCode: $('#zipCode').val()
},
};
console.log(addressDetails);
Meteor.call('addNewAddress', addressDetails, currentUserId, function(error) {
if (error) {
alert(error.reason);
} else {
console.log('success!');
Router.go('Admin');
}
});
},
});
Here's my addAddress method:
Meteor.methods({
'addNewAddress': function(addressDetails, currUserId) {
var currentUserId = currUserId;
Meteor.users.update(currentUserId, {$addToSet:
{'address.streetAddress': addressDetails.streetAddress,
'address.city': addressDetails.city,
'address.state': addressDetails.state,
'address.zipCode': addressDetails.zipCode
}
});
}
});
Note - when I do console.log(addressDetails), it prints out the address details just fine.
Can someone help? Thank you in advance!!
Yeah, that error kinda sends you in the wrong direction. Regardless, you're using $addToSet on an object. Do this:
Meteor.users.update(currentUserId, {$set: addressDetails.address}
Try the following code:
Meteor.users.update(
{$currUserId},
{$addToSet:
{'address.streetAddress': addressDetails.streetAddress,
'address.city': addressDetails.city,
'address.state': addressDetails.state,
'address.zipCode': addressDetails.zipCode
}
});