clean() method of a composed schema does not behave as expected
See original GitHub issueHello !
I’ve stumbled upon a problem while working with simple-schema, collection2 and autoForm. I think my issue is related to simple-schema, though.
TL;DR
When I use the clean() method of a schema that’s build with an existing schema and some additional field (as in the bottom of this doc’s section), it doesn’t generate the autoValues that are defined in the pre-existing schema. So, when I try to check a doc against the schema after a clean(), an error is thrown telling me that the field has to be defined.
Explications
I’ve got several field that I reuse heavily throughout my entire app. Thus, I’ve created a special schema that only defines these field. As you can see, both the fields are given an autoValue attribute that automatically generates the right values.
Schemas.Inserted = new SimpleSchema({
insertedAt: {
type: Date,
label: "Date d'insertion",
autoValue: function () {
if (this.isInsert) {
return new Date;
} else if (this.isUpsert) {
return {$setOnInsert: new Date};
} else {
this.unset();
}
},
autoform: {
omit: true
}
},
insertedBy: {
type: String,
label: "Inséré par",
autoValue: function () {
if (this.isInsert) {
return Meteor.userId();
} else if (this.isUpsert) {
return {$setOnInsert: Meteor.userId()};
} else {
this.unset();
}
},
autoform: {
omit: true
}
}
});
As I said, I’m reusing this schema to build the others. In the present case, the schema that’s causing the error is this one :
Schemas.Category = new SimpleSchema([Schemas.Inserted, {
name: {
type: String,
label: "Nom"
},
otherFieldThatAreNotRelevant: {
...
}
}]);
The schema is working well when called by a quickForm with the ‘insert’ type : both the insertedAt and insertedBy field are generated correctly. But, when I want to use a ‘method’ type quickForm and use the clean() function in the server method to pass a check() validation, it fails.
This is the server method that’s called by the quickForm :
Meteor.methods({
addCategory: function (doc) {
console.log("Received doc", doc);
Categories.simpleSchema().clean(doc); // this is the collection to which the Category schema is attached
console.log("Cleaned doc", doc); // exactly the same as the 'received doc'
check(doc, Categories.simpleSchema()); // this fails
// the method should continue after that
}
});
And the error I got :
I20150704-01:48:53.891(2)? Received doc { name: 'Nouvelle', initials: 'NOU', level: 4, parent: 'BAA' }
I20150704-01:48:53.891(2)? Cleaned doc { name: 'Nouvelle', initials: 'NOU', level: 4, parent: 'BAA' }
I20150704-01:48:53.891(2)? Exception while invoking method 'addCategory' Error: Match error: Le champ Date d'insertion doit être renseigné
I20150704-01:48:53.891(2)? at [object Object].SimpleSchema.condition (packages/aldeed:simple-schema/simple-schema.js:602:1)
I20150704-01:48:53.891(2)? at checkSubtree (packages/check/match.js:220:1)
I20150704-01:48:53.892(2)? at check (packages/check/match.js:32:1)
I20150704-01:48:53.892(2)? at [object Object].Meteor.methods.addCategory (app\server\controllers\categories.js:6:3)
I20150704-01:48:53.892(2)? at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1617:1)
I20150704-01:48:53.892(2)? at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20150704-01:48:53.892(2)? at packages/ddp/livedata_server.js:647:1
I20150704-01:48:53.892(2)? at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20150704-01:48:53.892(2)? at [object Object]._.extend.protocol_handlers.method (packages/ddp/livedata_server.js:646:1)
I20150704-01:48:53.892(2)? at packages/ddp/livedata_server.js:648:1
I20150704-01:48:53.899(2)? Sanitized and reported to the client as: Le champ Date d'insertion doit être renseigné [400]
I20150704-01:48:53.899(2)?
Can someone explain to me how I could achive a correct clean ? I just hope that I’m making some sort of mistake and that it’s not a real issue ^^
Thanks !
Issue Analytics
- State:
- Created 8 years ago
- Comments:5
Top GitHub Comments
OMG I eventually find the solution. To be short : Server side, just an insert should be enough. (and normally an update also) On this conversation, aldeed says that “…it is redundant to clean and validate in your method. Just call Exercises.update, which will already clean and validate every operation.” My problem was that I was using this.userId in the autovalue function and it doesn’t work server side. So I used Meteor.userId().
I had to use this interesting piece of code to know which field was wrong :
and FYI, if the clean() function does not work it’s because it needs context. It should be used like this :
Good explanation @LasTIC - that helped me fix a separate issue I was having (also from not calling clean() with context. Thanks!