Meteor-Community-Packages / meteor-simple-schema

Meteor integration package for simpl-schema
https://github.com/Meteor-Community-Packages/meteor-simple-schema
MIT License
919 stars 161 forks source link

How to display "Inner" schema messages to client? #712

Closed juhojo closed 6 years ago

juhojo commented 6 years ago

Hey,

I have an issue regarding how to display an error message that is from an "inner" Schema. My code is similar to the following:

// File types that are allowed
allowedFileTypes = [
  'application/pdf', // .pdf
  'application/msword', // .doc
  ...
  'image/png', // .png
];
// The Inner Schema that is used as the wrapper attributes' type
FileSchemaClient = new SimpleSchema({
  fileName: {
    type: String,
  },
  size: {
    type: Number,
    optional: true,
  },
  fileType: {
    type: String,
    allowedValues: allowedFileTypes,
  },
});
// Wrapping Schema
filesSchemaClient = new SimpleSchema({  
  file1: {  
    type: FileSchemaClient,  
  },
  ...
  fileN: {  
    type: FileSchemaClient,  
  },  
  fileArray: {  
    type: [FileSchemaClient],
  },  
});
// The message that I would like to display but do not know how to...
FileSchemaClient.messages({
  'notAllowed fileType': 'Your file format is not allowed.',
});

I have a ton of files in my filesSchemaClient and I wish to keep my program as DRY as possible, hence the issue. How to display the error message on client, do I have to use custom() method or repeat the three attributes (fileName, size and fileType) on each file to show the invalidKeys or is there a cleaner solution for my problem?

Thanks in advance.

juhojo commented 6 years ago

I managed to solve my problem after taking a closer look in the documentation.

For others facing a similar issue: I declared a global error message for the notAllowed attribute in the Wrapper Schema

filesSchemaClient.messages({
  notAllowed: 'Your file format is not allowed.',
});

On the client side I did loop the keys as following:

const ik = fileVContext.invalidKeys();
if (ik.length > 0) {
  ik.forEach((key) => {
    if (key.name.substring(0, key.name.indexOf('.')) === name) {
      message = fileVContext.keyErrorMessage(key.name);
    }
  });
}

In my case the error keys were as following: { name: 'file1.fileType', type: 'notAllowed' } so I made a simple comparison using substring to only pick the file1 part (the actual name in the filesSchemaClient Schema).

To find more from the documentation check out Getting a List of Invalid Keys and Validation Error Messages.