I'm working a project developing by Meteor.js & now I'm working for a validation something like that
import SimpleSchema from 'simpl-schema';
const CompanySchema = new SimpleSchema({
company_name: {
type: String,
min: 5,
max: 50,
label: "Company Name"
}
});
Company.attachSchema(CompanySchema);
but in the console showing like below image
but when trying to keep the "Error" like this way
console.log(err.Error);
it's showing
undefined
here is insert functionalities
Company.insert(
{
company_name: inputs.companyName.value,
},
function(err) {
if (err) {
console.log(err);
} else {
console.log('Inserted successfully');
}
}
);
what's the issue actually.
Thanks
When your client-side Mongo insert fails it produces a native Error. If you log it's name, message and stack it shows the expected properties of an Error:
Company.insert(
{
company_name: inputs.companyName.value,
},
function(err) {
if (err) {
console.log(err.name);
console.log(err.message);
console.log(err.stack);
}
}
);
Produces:
Error
Company Name must be at least 5 characters in company insert
Error: Company Name must be at least 5 characters in company insert
at getErrorObject (collection2.js:498)
at doValidate (collection2.js:470)
at Collection.Mongo.Collection.(:3000/anonymous function) [as insert] (http://localhost:3000/packages/aldeed_collection2.js?hash=9ed657993899f5a7b4df81355fd11d6b77396b85:286:14)
at Blaze.TemplateInstance.helloOnCreated (main.js:10)
at blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3398
at Function.Template._withTemplateInstanceFunc (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3769)
at fireCallbacks (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3394)
at Blaze.View.<anonymous> (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3474)
at fireCallbacks (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:2014)
at Object.Tracker.nonreactive (tracker.js:603)
The attribute err.error in contrast is part of the Meteor.Error, which is thrown if the insert fails inside a Meteor Method.
This would be the case for example in such code:
Meteor.call('someInserMethod', { company_name: 'abc' }, (err, res) => {
console.log(err) // this error is a Meteor.Error
})
Related
Trying to make a custom async schema validator in mongoose, to check that "tags" for a course being created contains at least one item. (Using SetTimeout() to simulate async). The part of the Schema for tags is :
tags: {
type: Array,
validate: {
isAsync: true,
validator: function (v, cb) {
setTimeout(() => {
//do some async work
const result = v && v.length > 0;
cb(result);
}, 3000);
},
message: "A course should have at least one tag!",
},
},
The code for creating a course is:
async function createCourse() {
const course = new Course({
name: "Node.js Course",
author: "Anon",
category: "web",
tags: [],
isPublished: true,
price: 13,
});
try {
const result = await course.save();
cl("createCourse result", result);
} catch (ex) {
cl("createCourse validate error", ex.message);
}
}
createCourse();
I have an empty array for tags and expected the caught error "A course should have at least one tag". Instead I am getting TypeError: cb is not a function for cb(result), the callback result? Even if I have an item in the tags array it still gives the callback error and in fact it displays the createCourse result BEFORE the schema async completes and then throws the error when it does complete! (If I dont use the async validator but just a plain validator then it works fine).
tags: {
type: Array,
validate: {
validator: function(v) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(v && v.length > 0);
}, 3000);
})
},
message: 'A course should have at least one tag.'
}
},
After trial and error, I came up with the solution below. No changes needed to createCourse(), just to the Schema tags section and added a delay function.
tags: {
type: Array,
validate: {
//isAsync: true,
validator: async function (v) {
await delay(3);
const result = v && v.length > 0;
return result;
},
message: "A Document should have at least one tag!",
},
},
And this calls a delay function, used to simulate a "real" async situation where this data may be being saved to a remote server.
const delay = (n) => {
return new Promise(function (resolve) {
setTimeout(resolve, n * 1000);
});
};
I am using Ostrio/files also known as meteor-files (from VeliovGroup or keenethics) on the server-side to insert a file to db.images, db.fs.files and db.fs.chunks. My code only manages to insert a record only in db.images and nothing on fs.files and fs.chunks. My code is as follows:
Images.write(this.bodyParams.file, {
fileName: 'SignUpTermsAndConditions_' + this.bodyParams.name,
fielId: 'abc123myId', //optional
type: 'application/vnd.oasis.opendocument.text',
meta: {owner: this.userId,createdAt: new Date()}
}, function (error, fileRef) {
if (error) {
throw error;
} else {
console.log(fileRef.name + ' is successfully saved to FS. _id: ' + fileRef._id);
}
});
I am able to insert a file from the client into db.images, db.fs.files and db.fs.chunks using the following code:
Images.insert({
file: file, // where var file = e.currentTarget.files[0];
fileName: fileName + e.currentTarget.files[0].name,
onStart: function () {
},
onUploaded: function (error, fileObj) {
if (error) {
alert('Error during upload: ' + error);
} else {
}
},
streams: 'dynamic',
chunkSize: 'dynamic'
});
The server code as per the first snippet above is one that is not working correctly or as expected.Please help.
For info: how I setup my gridFS is as per
this link. My Images.write as per my second code snippet above is as per the code in
this link. In short I am following the documentation but my server Images.write is not working as expected.Please help!
I found the answer to my question. I set the fourth parameter to true i.e proceedAfterUpload=true and records are inserted in db.fs.files and db.fs.chunks. This is as per the write method documentation, it is slightly vague though. Here is the amended code:
Images.write(this.bodyParams.file, {
fileName: 'SignUpTermsAndConditions_' + this.bodyParams.name,
fielId: 'abc123myId', //optional
type: 'application/vnd.oasis.opendocument.text',
meta: {owner: this.userId,createdAt: new Date()}
}, function (error, fileRef) {
if (error) {
throw error;
} else {
console.log(fileRef.name + ' is successfully saved to FS. _id: ' + fileRef._id);
}
},proceedAfterUpload=true);
That's it.
PS: Make sure this.bodyParams.file is a buffer so that the inserted file is not corrupt - thanks to #dr.dimitru for advising me on inserting a buffer.
I'm trying to get a single text field to insert a string into my collection. I'm getting this error:
Exception while invoking method 'categories.insert' TypeError: func is not a function
at /var/www/node/lover/node_modules/simpl-schema/dist/doValidation.js:359:18
at Array.forEach (native)
at doValidation (/var/www/node/lover/node_modules/simpl-schema/dist/doValidation.js:358:17)
at ValidationContext.validate (/var/www/node/lover/node_modules/simpl-schema/dist/ValidationContext.js:217:57)
at [object Object].doValidate (packages/aldeed:collection2-core/collection2.js:399:33)
at [object Object].Mongo.Collection.(anonymous function) [as insert] (packages/aldeed:collection2-core/collection2.js:187:25)
at [object Object].Meteor.methods.categories.insert (server/methods.js:14:21)
at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1737:12)
at packages/ddp-server/livedata_server.js:719:19
at [object Object]._.extend.withValue (packages/meteor.js:1122:17)
Here is my Schema:
import { Mongo } from 'meteor/mongo';
var Categories = new Mongo.Collection('categories');
const CategorySchema = new SimpleSchema({
title: {
type: String,
label: "Title",
max: 255,
optional: true
},
created: {
type: Date,
label: "Date Category Created",
autoValue: () => {
if(this.isInsert){
return new Date();
}
}
},
updated: {
type: Date,
label: "Date Category Modified",
autoValue: () => {
if(this.isUpdate){
return new Date();
}
}
}
});
Categories.attachSchema(CategorySchema);
export default Categories;
The method to be called:
import { check } from 'meteor/check';
import { Categories, Elections, Nominees, Users, Votes } from '../collections';
Meteor.methods({
'categories.insert'(title){
check(title, String);
return Categories.insert({title: title});
}
});
And then I call it:
...
Template.settings.events({
'click #newCategoryButton'(e){
let title = $("#newCategoryInput").val();
Meteor.call('categories.insert', title, (error, response) => {});
}
});
...
I can get it to work if I add {validate: false} to my insert statement, which leads me to believe that it's a validation issue. I've gone through all the docs and a few blogs and tuts but can't find any instructions on how to insert data to my collection when using collection2 and simple-schema if it's not that standard way. In fact, if you scroll a few lines up on the collection2 documenation, the insert call is shown in basically the same form as I've written it.
I don't want to pass {validate: false} in with my insert calls as it defeats the purpose of adding a schema to my collections in the first place.
Desperate for help, been stuck on this for hours.
While trying to upload a File to my Database, I am getting a Match Error that is preventing the File to be stored.
Here is the Basic code:
The Initialization:
UserImages = new FS.Collection("userImages", {
stores: [new FS.Store.FileSystem("userImages", {path: "~/uploads"})],
filter: {
maxSize: 1048576, //in bytes
allow: {
contentTypes: ['image/*'],
extensions: ['png', 'jpg']
},
onInvalid: function (message) {
if (Meteor.isClient) {
alert(message);
} else {
console.log(message);
}
}
}
});
if(Meteor.isServer){
UserImages.allow({
insert:function(userId, doc){
return true;
},
update:function(userId, doc, fields, modifier){
check(doc, Object);
return true;
},
remove:function(){
return true;
}
})
}
The Client Code:
Template.editProfile.events({
'change #profileUpload':function(event, template){
var files = event.target.files;
for (var i = 0, ln = files.length; i < ln; i++) {
UserImages.insert(files[i], function (err, fileObj) {
if(err){
console.log(err);
}
});
}
}
});
Strangly enough, if i run a console.log(typeof file) it gives me back an Object. But when i check the File against an Object with check(file, Object) it gives me this Error:
This is the Stack from the Server:
Exception in setTimeout callback: Error: Match error: Expected plain object
at checkSubtree (packages/check/match.js:279:1)
at check (packages/check/match.js:32:1)
at UserImages.allow.update (app/server/allowances.js:91:7)
at packages/mongo/collection.js:1041:1
at Array.every (native)
at Function._.every._.all (packages/underscore/underscore.js:219:1)
at [object Object].Mongo.Collection._validatedUpdate (packages/mongo/collection.js:1038:1)
at [object Object].m.(anonymous function) (packages/mongo/collection.js:851:1)
at Object.methods.rateLimit.callFunctionsInQueue (packages/matteodem:easy-security/lib/easy-security.js:72:1)
at packages/matteodem:easy-security/lib/easy-security.js:116:1
Has anyone encountered this problem or has a solution for a workaround? I've tried all kinds of workarounds also with Match.Any but than I get an error telling me that all Arguments have not been run against the check();
I checked the issues in here:
https://github.com/CollectionFS/Meteor-cfs-base-package/issues
https://github.com/CollectionFS/Meteor-CollectionFS/issues
but could not find a solution so far.
Thanks for the help!
I am looking for a way to retrieve all validation errors. (I'm using Collection2 and SimpleSchema)
Consider this code:
Foo.insert({
title: '',
description: ''
}, function(error, result) {
console.error(error);
});
output:
{
message: 'Title may not be empty.',
invalidKeys: [
0: {
name: 'title',
type: 'required',
value: ''
},
1: {
name: 'description',
type: 'required',
value: ''
}
]
}
I would like to have all the error messages that are related to validation.
Unfortunately I couldn't find any solution for this.
SOLUTION:
I've found a satisfiable solution
Foo.simpleSchema().namedContext().keyErrorMessage('title');
I ran into the same problem and my solution was to insert said errors into a client mongo error collection which would then display the errors to the user. The following is what I came up with:
Schema
Schema.newUser = new SimpleSchema({....});
Client Side Validation
function tokenRegistration (newUser) {
var valContext = Schema.newUser.namedContext('tokenRegForm');
if (!valContext.validate(newUser)) {
var keys = valContext.invalidKeys();
_.each(keys, function (value) {
var error = value.name,
message = valContext.keyErrorMessage(error);
return ErrorMessage.insert({errormessage: message})
});
}
}