node-convict icon indicating copy to clipboard operation
node-convict copied to clipboard

default value for array items

Open Darkein opened this issue 4 years ago • 8 comments

Hello,

i'm using the array validator in my schema.

Unfortunately, because it use a new convict instance to validate the schema, the default values of the elements in my array are not set.

I tried to get my active instance, but because I don't know where i am in the schema during the validation, I can't set the values on my own.

If someone as any idea ?


this is the validator:

convict.addFormat({
  name: 'source-array',
  validate: function(sources, schema) {
   /* ... */
    for (source of sources) {
      convict(schema.children).load(source).validate();
    }
  }
});

my schema:

defaultValue:
  format: String
  default: 'default'
contexts:
  format: array
  default: []
  children:
    defaultValue:
      format: String
      default: 'default'
    name:
      format: String
      default: null

my config file:

contexts:
  - name: TEST1

what I want:

{
   "defaultValue": "default",
   "contexts":[
      {
         "defaultValue": "default",
         "name": "TEST1"
      }
   ]
}

what I have:

{
   "defaultValue": "default",
   "contexts":[
      {
         "name": "TEST1"
      }
   ]
}

Darkein avatar Apr 24 '20 08:04 Darkein

I can make a PR if needed, but I don't have any clue how to do it properly

Darkein avatar Apr 24 '20 09:04 Darkein

In my fork, I did: https://github.com/A-312/node-convict/commit/c9d24109dc798071bf62fe0d51d1e87ac57e5509#diff-9a1c05ec2f523aa189f25a817c2b605dR368-R381 (It is maybe usefull to have a different messages displays when you want return several error).

Like this:

Validate failed because wrong value(s):
  - root: Custom format "children" tried to validate something and failed:
    1) germany:
      - name: must be of type String: value was 1
    2) italy:
      - subregion: must be of type String: value was 2 

I can make a PR if needed, but I don't have any clue how to do it properly

You have to had the fullName variable like a third arg:

https://github.com/mozilla/node-convict/blob/903638f558db071ddf44c311e4c211e738216b6f/packages/convict/src/main.js#L298

newFormat(x, this, fullName) 

A-312 avatar Apr 24 '20 11:04 A-312

Thanks for answer.

I already tried with fullname but it's not enough if I have sub array. But if I can pass the current instance of convict it could do the job :)

I will give a try

Darkein avatar Apr 27 '20 07:04 Darkein

I already tried with fullname but it's not enough if I have sub array.

I think my solution handle this

A-312 avatar Apr 27 '20 10:04 A-312

it works by adding fullname and instance, thanks :)

export default {
  name: 'source-array',
  validate: (
    sources: any,
    schema: { children: string | convict.Schema<any> },
    fullname: string,
    instance: convict.Config<any>,
  ) => {
    if (!Array.isArray(sources)) {
      throw new Error('must be of type Array');
    }

    const data = sources.map(source => 
        convict(schema.children)
          .load(source)
          .validate({ allowed: 'strict' })
          .getProperties();
    );

    instance.set(fullname, data);
  },
};

I forked node-convict to do it, but I can create a PR on your project if you want ?

Darkein avatar Apr 27 '20 13:04 Darkein

or: newFormat.call(instanceConvict, x, this, fullName)

and after: this.set(fullname, data)

A-312 avatar Apr 27 '20 14:04 A-312

yes, good idea too !

Darkein avatar Apr 27 '20 14:04 Darkein

Is there any fix available for this issue yet ,i am facing similar issue ,default values of children array objects are not being loading after upgrade to 6.0.1 ?

ashishmahawal avatar Oct 11 '21 10:10 ashishmahawal