Saving an object in mongodb - meteor

I am trying to save variant options as an object, something like that:
{'1' : {optionTitle: 'title', optionPrice: 12}, '2': {....}}
//schema
RestMenuVariants.attachSchema(new SimpleSchema({
restRefId: {type: String},
createdBy:{type: String},
title: {type: String},
options: {type: Object},
sortId: {type: String, optional: true},
createdAt: {type: Date}
}));
//part of the method addMenuVariantItem
return RestMenuVariants.insert({
restRefId: restId,
createdBy: Meteor.userId(),
createdAt: new Date(),
title: title,
options: options,
sort_id: sortId
});
// part of the event for loop which creates the object
variantOptions[i] = {optionTitle: $(element).val(), optionPrice: $(elementPrice).val()};
}
// and calling the method
Meteor.call('addMenuVariantItem', this._id, this.createdBy, variantTitle, variantOptions, function(error, result){.....})
I don't get any check or other errors, the variant is saved but when I look for the item at the console i see that the options is an empty object:
//var cursor = RestMenuVariants.findOne({_id: id});
//console.log(cursor.options)
Object {}
What am I missing?
Thanks.

It looks like variantOptions is being created as an array but your schema only expects an object.
Change:
options: {type: Object}
to
options: {type: [Object], blackbox: true },
in your schema definition.
The blackbox: true option tells simple-schema to ignore the structure of the objects being put into the options array.
Also note that an array is != a nested object with numbered keys as you have in your description. You won't get:
{
'1': {optionTitle: 'title', optionPrice: 12},
'2': {....}
}
Instead you'll see:
[
{ optionTitle: 'title', optionPrice: 12 },
{....}
]

Related

Query backlink on two fields with same type

I have a relationship between Product and its units describe in schema as below:
public static schema: Realm.ObjectSchema = {
name: Product.schemaName,
primaryKey: 'sku',
properties: {
name: {type: 'string'},
baseUnit: {type: SoldableUnit.schemaName},
derivedUnits: {type: 'list', objectType: SoldableUnit.schemaName},
},
};
public static schema: Realm.ObjectSchema = {
name: SoldableUnit.schemaName,
embedded: true,
properties: {
unitName: {type: 'string'},
sellingPrice: {type: 'double'},
weight: {type: 'float'},
barcode: {type: 'string', optional: true, indexed:true},
},
};
The idea is a product can have one baseUnit and many derivedUnits, and both baseUnit and derivedUnits are SoldableUnit with the same schema. I want to query product by barcode. Here I have to return the product, providing a barcode which maybe equals to barcode of baseUnit or derived units. After some research, I find out that I can use backlink to return inverse relationship. The problem here is SoldableUnit occurs both in baseUnit and derivedUnits and I dont know how to achieve this goals? And whether the schema design of Product is appropriate?

Aldeed Simple-Schema, how to use allowed values in a field from another one?

I am trying to build a kind of specific simple schema for a collection and i would like to make sure that :
when the user enter a new select in my selectsCollection, he will put one of the options value as selected value.
For example:
SelectsCollection.insert({name:"SelectOne",deviceType:"Select",options:["option1","option2","option3"],value:"option4",description:"This is the first select"});
this do not have to work. I want him to write only one of the 3 options.
Here my schema :
SelectsCollection = new Mongo.Collection('Selects'); //Create a table
SelectsSchema = new SimpleSchema({
name:{
type: String,
label:"Name",
unique:true
},
deviceType:{
type: String,
allowedValues: ['Select'],
label:"Type of Device"
},
options:{
type: [String],
minCount:2,
maxcount:5,
label:"Select Values"
},
value:{
type: String,
//allowedValues:[options] a kind of syntax
// or allowedValues:function(){ // some instructions to retrieve the array of string of the option field ?}
label:"Selected Value"
},
description:{
type: String,
label:"Description"
},
createdAt:{
type: Date,
label:"Created At",
autoValue: function(){
return new Date()
}
}
});
SelectsCollection.attachSchema(SelectsSchema);
Any Idea ? :)
Thanks a lot !
This could be done with custom validation function of a field, inside this function you could retrieve values from other fields:
SelectsSchema = new SimpleSchema({
// ...
options: {
type: [String],
minCount: 2,
maxcount: 5,
label: "Select Values"
},
value: {
label: "Selected Value",
type: String,
optional: true,
custom() {
const options = this.field('options').value
const value = this.value
if (!value) {
return 'required'
}
if (options.indexOf(value) === -1) {
return 'notAllowed'
}
}
},
// ...
});
Look here custom-field-validation for more information

Subschema as array item with AutoForm, SimpleSchema

I am trying to get subschemas to work as an array, which I assume is the correct way to handle my problem (but please correct me if I am wrong!). I provide a simplified working example to show my problem, based on the BooksSchema example provided by the AutoForm package. In my example, I have a collection of Libraries, and one of the fields in the 'Libraries' object is supposed to be the library's collection of books. Rendering the AutoForm does not give me any input labels as defined in my Book collection, but instead just shows one (1) empty text input field.
Schemas:
import SimpleSchema from 'simpl-schema';
SimpleSchema.extendOptions(['autoform']);
BooksSchema = new SimpleSchema({
title: {
type: String,
label: "Title",
max: 200
},
author: {
type: String,
label: "Author"
},
copies: {
type: Number,
label: "Number of copies",
min: 0
},
lastCheckedOut: {
type: Date,
label: "Last date this book was checked out",
optional: true
},
summary: {
type: String,
label: "Brief summary",
optional: true,
max: 1000
}
}, { tracker: Tracker });
LibrariesSchema = new SimpleSchema({
collection: {
type: Array
},
'collection.$': {
type: BooksSchema,
minCount: 1
}
});
LibrariesSchema.extend(BooksSchema);
Libraries = new Mongo.Collection("libraries");
Libraries.attachSchema(LibrariesSchema);
AutoForm:
{{> quickForm collection="Libraries" id="insertBookForm" type="insert"}}
Thank you so much in advance for your time, really been struggling with this for a long time now!
In my case I was indeed able to resolve the issue by using John Smith's example without the brackets.
LibrariesSchema = new SimpleSchema({
'books': {
type: BooksSchema,
minCount: 1
}
});
LibrariesSchema = new SimpleSchema({
'books': {
type: [BooksSchema],
minCount: 1
}
});
Arrays of a specific types, for use in check() or schema definitions, are specified as [SomeType], eg. [String], or [BooksSchema] in your case.

How to skip validation of object properties for type: [Object]

I'm trying to validate an Array of Objects with Simple-schema..
validate: new SimpleSchema({
orderId: {type: String},
skins: {type: [Object]}
}).validator(),
..but it seems that Simple-schema wants me to also validate every single property on every object inside that array, since i'm constantly getting "keyNotInSchema" type validationErrors:
skins.0.appid is not allowed by the schema
Is there any way to cancel validation of each object's property and to instruct Simple-Schema that i want just an "Array of Objects"?
You must declare that this is a blackbox object:
validate: new SimpleSchema({
orderId: {type: String},
skins: {type: [Object], blackbox: true}
}).validator(),

Collection2 removes object properties

This is my simplified collection & its schema:
Comments = new Mongo.Collection('comments');
Comments.schema = new SimpleSchema({
attachments: {type: [Object], optional: true},
});
Comments.attachSchema(Comments.schema);
And this is my simplified method:
Meteor.methods({
postComment() {
Comments.insert({
attachments: [{type:'image', value:'a'}, {type: 'image', value:'b'}]
});
}
});
After invoking the method, this is the document I've got in MongoDB:
{
"_id" : "768SmgaKeoi5KfyPy",
"attachments" : [
{},
{}
]
}
The objects in the array don't have any properties!
Now if I comment this line out:
Comments.attachSchema(Comments.schema);
and call the method again, the inserted document now seems correct:
{
"_id" : "FXHzTGtkPDYtREDG2",
"attachments" : [
{
"type" : "image",
"value" : "a"
},
{
"type" : "image",
"value" : "b"
}
]
}
I must be missing something fundamental here. Please enlighten me.
I'm using the latest version of Meteor (1.2.1).
From the simple-schema docs:
If you have a key with type Object, the properties of the object will be validated as well, so you must define all allowed properties in the schema. If this is not possible or you don't care to validate the object's properties, use the blackbox: true option to skip validation for everything within the object.
So you'll want to add blackbox:true to your attachments' options.
Comments.schema = new SimpleSchema({
attachments: {type: [Object], optional: true, blackbox: true},
});

Resources