javascriptmeteorsimple-schema

SimpleSchema validation for object array


I would like to validate this object array:

[
    {
        _id     : 'NpxZFT4TwfDvwbtKX',
        parent: 'T4TwfDvwbtKXNpxZF',
        order:  1
    }
]

How do I do that, as this is not working:

new SimpleSchema({
    _id   : { type: SimpleSchema.RegEx.Id },
    parent: { type: SimpleSchema.RegEx.Id },
    order : { type: Number }
})

How would the validation look like by using check()?


Solution

  • The cool thing about validated method is, that you can use a seperate schema for your method than for the documents. This allows you to pass objects and arrays and anything else to the method and process your documents in behalf of the data.

    So what about the schema you created before? This is still in use! It is checking FOR EACH insert or update of a document in your collection, if the document fits the given schema.

    Code Example:

    import {Meteor} from 'meteor/meteor';
    import {Mongo} from 'meteor/mongo';
    import {ValidatedMethod} from 'meteor/mdg:validated-method';
    import {Random} from 'meteor/random';
    
    import SimpleSchema from 'simpl-schema';
    
    // schema for document on collectionm level
    const documentSchema = new SimpleSchema({
        // id optional otherwise you can't insert new docs
        _id: {type: SimpleSchema.RegEx.Id, optional: true},
        parent: {type: SimpleSchema.RegEx.Id},
        order: {type: Number}
    });
    
    // attach schema to a new collection
    const testCollection = new Mongo.Collection("testcollection");
    testCollection.schema = documentSchema;
    testCollection.attachSchema(documentSchema)
    
    
    // create method schema
    // see that we attach the document schema
    // as type of the items of the array
    const methodSchema = new SimpleSchema({
        data: {type: Array},
        "data.$": {type: documentSchema},
    });
    
    // insert method using the method schema
    const insertArrayMethod = new ValidatedMethod({
        name: "insert.array.method",
        validate: methodSchema.validator(),
        run({data}){
            const ret = [];
            for (let input of data) {
                const tmp = Object.assign({}, input);
                tmp._id = testCollection.insert(input);
                ret.push(tmp);
            }
            return ret;
        },
    });
    
    // update method using the method schema
    const updateArrayMethod = new ValidatedMethod({
        name: "update.array.method",
        validate: methodSchema.validator(),
        run({data}){
            const ret = [];
            for (let input of data) {
                ret.push(testCollection.update(input._id, {$set: {parent: input.parent, order: input.order}}));
            }
            return ret;
        },
    });
    
    
    Meteor.startup(() => {
        const data = [
            {parent: Random.id(17), order: 0},
            {parent: Random.id(17), order: 1},
            {parent: Random.id(17), order: 2},
        ];
        console.log("insert data")
        console.log(data);
    
        const results = Meteor.call("insert.array.method", {data: data});
        console.log("insert result");
        console.log(results);
    
        for (let element of results) {
            element.order += 5;
        }
        console.log("update data");
        console.log(results);
    
        // note thet the input variablle in the validated method has to be called data
        const updateResult = Meteor.call("update.array.method", {data: results});
        console.log("update result");
        console.log(updateResult);
    });
    

    Console Output:

    I20170701-12:21:38.302(2)? insert data        
    I20170701-12:21:38.319(2)? [ { parent: 'wkh3C6NSvZqrewxLh', order: 0 },
    I20170701-12:21:38.322(2)?   { parent: 'ezfBAtZrgXgG8dANy', order: 1 },
    I20170701-12:21:38.342(2)?   { parent: 'H4eXyR6FJ9sts6Nn2', order: 2 } ]
    I20170701-12:21:38.616(2)? insert result
    I20170701-12:21:38.621(2)? [ { parent: 'wkh3C6NSvZqrewxLh',
    I20170701-12:21:38.624(2)?     order: 0,
    I20170701-12:21:38.626(2)?     _id: 'et4hCu2osH7DnbhHo' },
    I20170701-12:21:38.633(2)?   { parent: 'ezfBAtZrgXgG8dANy',
    I20170701-12:21:38.636(2)?     order: 1,
    I20170701-12:21:38.641(2)?     _id: 'ysH3NaydR6PwdTQCr' },
    I20170701-12:21:38.656(2)?   { parent: 'H4eXyR6FJ9sts6Nn2',
    I20170701-12:21:38.659(2)?     order: 2,
    I20170701-12:21:38.660(2)?     _id: 'AQExATqWhGr26FN7A' } ]
    I20170701-12:21:38.673(2)? update data
    I20170701-12:21:38.681(2)? [ { parent: 'wkh3C6NSvZqrewxLh',
    I20170701-12:21:38.683(2)?     order: 5,
    I20170701-12:21:38.684(2)?     _id: 'et4hCu2osH7DnbhHo' },
    I20170701-12:21:38.696(2)?   { parent: 'ezfBAtZrgXgG8dANy',
    I20170701-12:21:38.698(2)?     order: 6,
    I20170701-12:21:38.700(2)?     _id: 'ysH3NaydR6PwdTQCr' },
    I20170701-12:21:38.701(2)?   { parent: 'H4eXyR6FJ9sts6Nn2',
    I20170701-12:21:38.705(2)?     order: 7,
    I20170701-12:21:38.707(2)?     _id: 'AQExATqWhGr26FN7A' } ]
    I20170701-12:21:38.712(2)? update result
    I20170701-12:21:38.714(2)? [ 1, 1, 1 ]
    

    Summary:

    method-schema - validates the input for a validated method document-schema - validates the input/update object for a mongo collection