I'm trying to add a value to a nested schema:
groups = new SimpleSchema({
title: { type: String, optional: true },
element: { type: [elements], optional: true }
});
elements = new SimpleSchema({
description:{ type: String, optional: true },
anything: { type: String, optional: true }
});
MongoDB.attachSchema(new SimpleSchema({
title: { type: String },
slug: { type: String, unique: true },
language: { type: String, defaultValue: "en" },
group: { type: [groups], optional: true },
}));
Now I want to add just a new element-description to an existing entry in the DB. I tried this, but it doesn't work.
Uncaught Error: When the modifier option is true, validation object must have at least one operator
var newElement = {
description: 'insert this as a new element description'
};
MongoDB.update({ _id: Id }, { $push: { 'group.element': newElement }}, function(error) { if(error) console.warn(error); });
Is it correct to use 'group.element' as a $push-parameter?
Update
I forgot the index of group: $push: { 'group.0.element': newElement }
Also I have to define elements before groups in the schema.
Related
I am using the mongoose updateMany() method and I also want to keep it a part of transaction. The documentation shows the example of save() where I can do something like Model.save({session: mySession}) but don't really know how to use it with for example Model.updateMany()
UPDATE:
For example I have two models called SubDomain and Service and they look like this respectively:
SUB-DOMAIN
{
name: {
type: String,
required: true,
},
url: {
type: String,
required: true,
unique: true,
},
services: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Service",
},
],
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
}
SERVICE:
{
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
price: { type: Number },
tags: { type: Array },
packages: [
{
name: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
},
],
map: { type: String },
isHidden: {
type: Boolean,
required: true,
default: false,
},
sortingOrder: { type: Number },
isForDomain: { type: Boolean, required: false, default: false },
isForSubDomain: { type: Boolean, required: false, default: false },
subDomains: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "SubDomain",
},
],
}
Now the main field here is the services field in SubDomain and subDomains field in Service.
The complicated part😅:
Whenever the user wants to create new service, I want to $push that service's _id into the array of services of all the subDomains inside that new service
And for that, I am using the updateMany() like this:
const sess = await mongoose.startSession();
sess.startTransaction();
const newService = new Service({
_id: mongoose.Types.ObjectId(),
subDomains: req.body.subDomains
...foo
})
await SubDomain.updateMany(
{ _id: { $in: req.body.subDomains } },
{ $push: { services: newService._id } }
);
The problem starts here, of course I can do:
newService.save({session: sess})
but how do I keep my SubDomain's updateMany in the same transaction (i.e sess)
I know my example is difficult to wrap your head around but I have tried to pick a simplest example rather than copying the exact same code which would have been a lot more difficult
I have the following Scheme:
dGroup = new SimpleSchema({
title: { type: String, optional: true },
element: { type: String, optional: true }
});
MongoDB.attachSchema(new SimpleSchema({
title: { type: String },
slug: { type: String, unique: true },
language: { type: String, defaultValue: "en" },
group: { type: [dGroup], optional: true },
}));
... and in the DB I got this:
{ "_id" : "ag9qXWpCYm87kZbEk", "title" : "Test", "slug" : "test", "language" : "en" }
Now I want to add a dGroup -> title:
updates['group.title'] = 'insert this as a new group title with no element';
MongoDB.update({ _id: Id }, { $push: updates }, function(error) { if(error) console.warn(error); });
But this doesn't work. So I need some help to add subdocuments in meteor in case they do not exist.
Try declaring your object first and push it properly, like this:
var newGroup = {
title: 'insert this as a new group title with no element'
};
MongoDB.update({ _id: Id }, { $push: {group: newGroup }}, function(error) { if(error) console.warn(error); });
I keep getting the error: Exception while invoking method 'createUser' Error: When the modifier option is true, validation object must have at least one operator when I try to create a user. I am using meteor-simple-schema, but none of the fixes with this error have worked for me. I have tried using blackbox and optional to see where the issue is but I keep getting the same error.
var Schemas = {};
Schemas.UserGamesPart = {
public: {
type: [String],
defaultValue: []
},
private: {
type: [String],
defaultValue: []
}
};
Schemas.UserGames = {
game1: {
type: Schemas.UserGamesPart
}
};
Schemas.UserProfile = new SimpleSchema({
games: {
type: Schemas.UserGames
}
});
Schemas.UpgradeDetails = new SimpleSchema({
subscribed_on: {
type: Date,
optional: true
},
stripe_charge_id: {
type: String,
optional: true
},
school_license: {
type: Boolean,
defaultValue: false,
optional: true
}
});
Schemas.UserProperties = new SimpleSchema({
paid: {
type: Boolean,
defaultValue: false
},
upgrade_details: {
type: Schemas.UpgradeDetails,
optional: true
}
});
Schemas.User = new SimpleSchema({
_id: {
type: String
},
username: {
type: String,
optional: true
},
emails: {
type: [Object]
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email,
optional: true
},
"emails.$.verified": {
type: Boolean,
optional: true
},
createdAt: {
type: Date
},
profile: {
type: Schemas.UserProfile,
blackbox: true,
optional: true
},
properties: {
type: Schemas.UserProperties,
blackbox: true,
optional: true
}
});
Meteor.users.attachSchema(Schemas.User);
My accounts.creaate user is as follows:
Accounts.createUser({
email: $('#email').val(),
password: $('#password').val(),
profile: {
games: {
game1: {
public: [],
private: []
}
}
}
});
Any ideas on how I can get this to work?
You forgot to add new SimpleSchema there in the beginning:
Schemas.UserGamesPart = new SimpleSchema({
public: {
type: [String],
defaultValue: []
},
private: {
type: [String],
defaultValue: []
}
});
Schemas.UserGames = new SimpleSchema({
game1: {
type: Schemas.UserGamesPart
}
});
Also I think your usage of the nested schemas is a little off. Only nest schemas when you need to reuse one. Creating a separate schema for UserGamesPart looks horrible. Try this instead:
Schemas.UserGames = new SimpleSchema({
game1: {
type: Object
}
'game1.public': {
type: [String],
defaultValue: []
},
'game1.private': {
type: [String],
defaultValue: []
}
});
This is shorter and easier to read.
I have this Schema (using meteor-collection2):
Settings = new Mongo.Collection("settings");
var Schema = {};
Schema.Settings = new SimpleSchema({
user_id: {
type: String,
optional: false
},
settings_firm_name: {
type: String,
optional: false
},
settings_firm_primary_branch: {
type: String,
optional: false
},
settings_firm_employees_num: {
type: Number,
optional: false,
min:1
},
settings_firm_address: {
type: String,
optional: false,
},
settings_firm_email: {
type: String,
regEx: SimpleSchema.RegEx.Email,
optional: false,
},
settings_firm_web_page: {
type: String,
optional: false,
},
settings_firm_contact_phone: {
type: String,
optional: false,
},
settings_firm_fax: {
type: String,
optional: false,
},
settings_firm_social: {
type: [Object],
optional: false,
},
"firm_social.$.name": {
type: String
},
"firm_social.$.link": {
type: String,
regEx:SimpleSchema.RegEx.Url
}
});
I want to add to my database data that is validated by this schema. settings_firm_social is array of object. That objects are created from three different input fields where each object have name and link fields. How can I insert that document in my database? I simply try with:
Settings.insert(settings, function(error,result){
if(error){console.log(error)}
});
But my array then is populated with three empty objects ({}).
EDIT
When I log settings object that I pass to Meteor method befor insert:
I20150627-00:29:36.523(2)? Server log
I20150627-00:29:36.543(2)? { settings_firm_name: 'Test',
I20150627-00:29:36.543(2)? settings_firm_primary_branch: 'test',
I20150627-00:29:36.543(2)? settings_firm_employees_num: '200',
I20150627-00:29:36.543(2)? settings_firm_address: 'Test',
I20150627-00:29:36.544(2)? settings_firm_contact_phone: '12345',
I20150627-00:29:36.544(2)? settings_firm_fax: '123445',
I20150627-00:29:36.544(2)? settings_firm_web_page: 'http://localhost:3000/settings/ZQwjxYzBuSfodxHvF',
I20150627-00:29:36.544(2)? settings_firm_email: 'test#hotmail.com',
I20150627-00:29:36.544(2)? settings_firm_social:
I20150627-00:29:36.545(2)? [ { name: 'Facebook',
I20150627-00:29:36.545(2)? link: 'http://localhost:3000/settings/ZQwjxYzBuSfodxHvF' },
I20150627-00:29:36.545(2)? { name: 'Twitter',
I20150627-00:29:36.546(2)? link: 'http://localhost:3000/settings/ZQwjxYzBuSfodxHvF' },
I20150627-00:29:36.546(2)? { name: 'LinkedIn',
I20150627-00:29:36.546(2)? link: 'http://localhost:3000/settings/ZQwjxYzBuSfodxHvF' } ],
I20150627-00:29:36.546(2)? user_id: 'ZQwjxYzBuSfodxHvF' }
After insert:
I20150627-00:31:23.185(2)? { settings_firm_name: 'Test',
I20150627-00:31:23.185(2)? settings_firm_primary_branch: 'test',
I20150627-00:31:23.185(2)? settings_firm_employees_num: 200,
I20150627-00:31:23.185(2)? settings_firm_address: 'Test',
I20150627-00:31:23.185(2)? settings_firm_contact_phone: '12345',
I20150627-00:31:23.186(2)? settings_firm_fax: '123445',
I20150627-00:31:23.186(2)? settings_firm_web_page: 'http://localhost:3000/settings/ZQwjxYzBuSfodxHvF',
I20150627-00:31:23.187(2)? settings_firm_email: 'test#hotmail.com',
I20150627-00:31:23.187(2)? settings_firm_social: [ {}, {}, {} ],
I20150627-00:31:23.187(2)? user_id: 'ZQwjxYzBuSfodxHvF' }
You can add a new schema object to validate settings_firm_social.
Schema.settings = new SimpleSchema({
settings_firm_social: {
type: [settingsFirmSocialSchema]
}
});
And then:
var settingsFirmSocialSchema = new SimpleSchema({
name: {
type: String
},
link: {
type: String
}
});
trying to read between StackOverflow and the documentation of meteor-simple-schema but can't find a solution. I'trying to insert data in the Meteor.users collection through a form. But keep getting an error:
Uncaught Error: When the modifier option is true, validation object must have at least one operator
checkModifier
# simple-schema-validation.js:271doValidation1 # simple-schema-validation.js:321doValidation # simple-schema-context.js:9simpleSchemaValidationContextValidate # simple-schema-context.js:44doValidate # collection2.js:317_.each.Mongo.Collection.(anonymous function) # collection2.js:154(anonymous function) # VM47084:2InjectedScript._evaluateOn # VM47083:883InjectedScript._evaluateAndWrap # VM47083:816InjectedScript.evaluate # VM47083:682
Any clue?
if (Meteor.isClient) {
Template.artistform.events({
'submit': function (event) {
event.preventDefault(); //prevent page refresh
var currentUserId = this.userId;
form={firstName:firstname.value, lastName:lastname.value};
Meteor.users.update({_id:currentUserId}, {$set:form});
}
});
}
And the Schema
Schema = {};
Schema.UserCountry = new SimpleSchema({
name: {
type: String,
optional: true
},
code: {
type: String,
regEx: /^[A-Z]{2}$/,
optional:true
}
});
Schema.UserProfile = new SimpleSchema({
firstName: {
type: String,
regEx: /^[a-zA-Z-]{2,25}$/,
optional: true
},
lastName: {
type: String,
regEx: /^[a-zA-Z]{2,25}$/,
optional: true
},
birthday: {
type: Date,
optional: true
},
category : {
type: String,
allowedValues: ['Painting', 'Music','Other'],
optional: true
},
website: {
type: String,
regEx: SimpleSchema.RegEx.Url,
optional: true
},
bio: {
type: String,
optional: true
},
country: {
type: Schema.UserCountry,
optional: true
}
});
Schema.User = new SimpleSchema({
email: {
type: String,
optional: true
},
"email.verified": {
type: Boolean,
optional: true
},
profile: {
type: Schema.UserProfile,
optional: true
},
createdAt: {
type: Date,
autoValue: function() {
if (this.isInsert) {
return new Date();
} else if (this.isUpsert) {
return {$setOnInsert: new Date()};
} else {
this.unset();
}
}
}
});
Meteor.users.attachSchema(Schema.User);
Many thanks.
Try this schema
Schema.User = new SimpleSchema({
email: {
type: Object
},
'email.address': {
type: String,
optional: true
},
"email.verified": {
type: Boolean,
optional: true
},
profile: {
type: Schema.UserProfile,
optional: true
},
createdAt: {
type: Date,
autoValue: function() {
if (this.isInsert) {
return new Date();
} else if (this.isUpsert) {
return {$setOnInsert: new Date()};
} else {
this.unset();
}
}
}
});
Btw if you are using account-password then this schema won't work as that package expect emails to be stored in a certain way.