skip to Main Content

I’ve looked through the previous questions and can’t seem to find the specific scenario, so apologies if you’ve seen this question before.

For brevity sake, I have the follow JSON

{
  "minimum": 123,
  "charges":[
    {"amount": 123, "billable": 456},
    {"amount": 234, "billable": 456},
  ]
}
  1. "minimum" is optional initially,
  2. both "amount" and "billable" are optional
  3. If "amount" is present in any of the objects in the "charges" array, then "minimum" is now required.

The following would be invalid:

{
  "charges":[
    {"billable": 456},
    {"amount": 234, "billable": 456}, // amount is present here, so "minimum" needs to be on the root node.
  ]
}

The following is valid:

{
  "charges":[
    {"billable": 456},
    {"billable": 456},
  ]
}

Is this behavior possible? Thank you, brain trust.

2

Answers


  1. Yes, it is possible. But I think that you will need to validate the schema by hand with some kind of function like this:

    const isValid = ( data ) => {
        /*
            the some: checks if any array elements pass a test
    
            the operator !!
            converts Object to boolean. If it was falsy (e.g., 0, null, undefined, etc.), it would be false, otherwise, true.
        */
    
        const mustContainMinimun = data.charges && data.charges.some(charge => !!charge.amount);
    
        if(mustContainMinimun){
            return !!data.minimum
        }
    
        return true;
    
    }
    

    here you can test the function with your 2 examples:

    const isValid = ( data ) => {
    
        const mustContainMinimun = data.charges && data.charges.some(charge => !!charge.amount);
        
        if(mustContainMinimun){
            return !!data.minimum
        }
    
        return true;
    
    }
    
    const obj01 = {
        "charges":[
          {"billable": 456},
          {"billable": 456},
        ]
    }
    
    const obj02 = {
        "charges":[
          {"billable": 456},
          {"amount": 234, "billable": 456}, // amount is present here, so "minimum" needs to be on the root node.
        ]
      }
    
    console.log( "isValid:", isValid( obj01 ) )
    console.log( "isValid:", isValid( obj02 ) )
    Login or Signup to reply.
  2. Given your requirements you would need to use the if and required keywords.

    {
      "if": {
        "type": "object",
        "properties": {
          "charges": {
            "type": "array",
            "items": {
              "not": {
                "required": [
                  "amount"
                ]
              }
            }
          }
        }
      },
      "else": {
        "required": [
          "minimum"
        ]
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search