I am using AJV trying to validate some data and dynamically require properties based on another property's value.
What I am trying to validate is:
- enabled is always required,
- if enabled = true then only one of the other properties (realtime, threshold or digest) must be provided,
Sample payloads and expected results:
Should pass
{
"notifications": {
"enabled": false
}
}
Should pass
{
"notifications": {
"enabled": true,
"realtime": true
}
}
Should pass
{
"notifications": {
"enabled": true,
"digest": true
}
}
Should pass
{
"notifications": {
"enabled": true,
"threshold": {}
}
}
Should fail because enabled = true but no other property is set.
{
"notifications": {
"enabled": true
}
}
Should fail because enabled = true and more than one other property is set.
{
"notifications": {
"enabled": true,
"threshold": {},
"digest: true
}
}
Here's the validation schema I am using:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Settings",
"type": "object",
"properties": {
"notifications": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"realtime": {
"type": "boolean"
},
"threshold": {
"type": "object",
"properties": {
"detections": {
"type": "number"
},
"elapsed": {
"type": "number"
}
},
"required": ["detections", "elapsed"]
},
"digest": {
"type": "boolean"
}
},
"required": ["enabled"],
"if": {
"properties": { "enabled": true }
},
"then": {
"oneOf": [
{ "required": [ "realtime" ] },
{ "required": [ "threshold" ] },
{ "required": [ "digest" ] }
]
}
}
}
}
Thank you!
Turns out I was very close and the problem was how the if statement was being evaluated for true. Here's the correct schema that validates (passes and fails) all examples above as expected:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Settings",
"type": "object",
"properties": {
"notifications": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"realtime": {
"type": "boolean"
},
"threshold": {
"type": "object",
"properties": {
"detections": {
"type": "number"
},
"elapsed": {
"type": "number"
}
},
"required": ["detections", "elapsed"]
},
"digest": {
"type": "boolean"
}
},
"required": ["enabled"],
"if": {
"enabled": {
"const": true
}
},
"then": {
"oneOf": [
{
"required": ["realtime"]
},
{
"required": ["threshold"]
},
{
"required": ["digest"]
}
]
}
}
}
}
This part did the trick:
"if": {
"properties": {
"enabled": {
"const": true
}
}
}
Related
I want to create a new component having the user selected number of records of a collection type named articles . I dont need the user(admin) to select the related articles but only the number of published recent .
i have done this in my json file
{
"kind": "collectionType",
"collectionName": "pages",
"info": {
"singularName": "page",
"pluralName": "pages",
"displayName": "Page",
"description": ""
},
"options": {
"draftAndPublish": true
},
"pluginOptions": {
"i18n": {
"localized": true
}
},
"attributes": {
"title": {
"type": "string",
"pluginOptions": {
"i18n": {
"localized": true
}
},
"required": true
},
"description": {
"type": "text",
"pluginOptions": {
"i18n": {
"localized": true
}
}
},
"page_components": {
"type": "dynamiczone",
"components": [
"sections.hero",
"sections.section-with-buckets",
"sections.section",
"sections.section-with-cards",
"sections.rich-text",
"sections.section-with-articles"
],
"pluginOptions": {
"i18n": {
"localized": true
}
}
},
"seo": {
"type": "component",
"repeatable": false,
"pluginOptions": {
"i18n": {
"localized": true
}
},
"component": "meta.metadata",
"required": true
},
"url": {
"pluginOptions": {
"i18n": {
"localized": false
}
},
"type": "string",
"regex": "^$|^[a-zA-Z/-]+$"
}
}
}
but i want to be able to fetch the n number of recent articles which is another collection type
I am trying to create a form using the Angular JSON Schema Form. I want one field (dropdown1) to be required when another field (number1) is populated. I am able to get the following form + schema working in the SchemaForm.io Sandbox, but when I put it into my site, the dropdown field is missing.
Here is my schema:
{
"type": "object",
"properties": {
"isChecked": {
"title": "checked?",
"type": "boolean"
},
"text1": {
"title": "text1",
"type": "number",
"minimum": 0,
"maximum": 100,
"condition": "model.isChecked"
},
"number1": {
"title": "number1",
"type": "number",
"minimum": 0,
"condition": "model.isChecked"
},
"dropdown1": {
"title": "",
"type": "string",
"enum": ["Days", "Months", "Years"],
"condition": "model.isChecked"
},
"comment": {"type": "string", "Title": "Comment"}
}
}
Here is my form:
[
"isChecked",
{
"key": "text1",
"type": "decimal",
"validationMessages": {
"maximum": "text1 must be 100 or lower.",
"minimum": "text1 must be 0 or higher.",
"required": "This field is required"
},
"required": false
},
{
"key": "number1",
"type": "number",
"validationMessages": {
"minimum": "number1 must be 0 or higher."
},
"required": false
},
{
"key": "dropdown1",
"required": false,
"condition": "model.number1 === null"
},
{
"key": "dropdown1",
"required": true,
"condition": "model.number1 > 0",
"validationMessages": {
"required": "dropdown1 is required."
}
},
{
"key": "comment",
"type": "textarea"
}
]
You can use the "dependencies" property (https://json-schema.org/understanding-json-schema/reference/object.html#property-dependencies). The example requires billing_address to be present when a credit_card is provided:
{
"type": "object",
"properties": {
"credit_card": {
"type": "number"
},
"billing_address": {
"type": "string"
}
},
"dependencies": {
"credit_card": [
"billing_address"
]
}
}
This implementation supports "dependencies":
https://github.com/dashjoin/json-schema-form
You can check out the online example here:
https://dashjoin.github.io/#/example/dependencies
Here is the solution I found:
"condition": {
"functionBody": "return model.number1 === undefined && model.isChecked"
}
Hello I am new in Loopback
Here I am using loopback, mongodb, currently I have two collection with me, i.e. Company and Employee.
In employee collection, I am referring the company as a foreign key in employee table(means collection in mongo).
Company.json
"properties": {
"_id": {
"type": "number"
},
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
},
Employee.json
"properties": {
"name": {
"type": "string",
"required": true
},
"age": {
"type": "number",
"required": true
},
"department": {
"type": "string",
"required": true
},
"city": {
"type": "string",
"required": true
},
"salary": {
"type": "number",
"required": true
},
"componyId": {
"type": "objectid",
"required": true
}
},
"validations": [],
"relations": {
"compony": {
"type": "belongsTo",
"model": "Company",
"foreignKey": "componyId"
}
},
Please let me where I am get in wrong here...
empoyee.js
module.exports = function(Employee) {
console.log('Employee....:', Employee);
Employee.findSalary = function(value, cb) {
console.log('Employee value....:', value, cb);
Employee.find({
where: {
salary: {
gte: value,
},
},
include: {
relation: 'compony',
},
}, cb);
};
Employee.remoteMethod('findSalary', {
accepts: {
arg: 'salary',
type: 'number',
},
returns: {
arg: 'salarys',
type: 'array',
},
http: {
path: '/find-salary',
verb: 'get',
},
});
};
Thanks,
I think you should remove this part:
"componyId": {
"type": "objectid",
"required": true
}
and
include: {
relation: 'compony',
}
could be just
include: 'compony'
and I think you have a typo in 'compony' but you consistently use this name so it shouldn't be an origin of a problem just a side note
I am trying to query my data the following way:
const filter = {where: {activity_id: activity_id, include: {relation: 'planGoal', scope: {where: {activity_goal_id: goal_id}}}}};
However this doesn't seem to work only the activity_id filter is applied and the wrong data is returned.
So my question is how do I query data within an include? and is it even possible?
For reference, here are the models in question:
{
"name": "plan_goal_has_action_option",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"id": {
"type": "number"
},
"activity_id": {
"type": "number"
},
"plan_has_goal_id": {
"type": "number"
},
"action_option": {
"type": "string"
}
},
"validations": [],
"relations": {
"planGoal": {
"type": "belongsTo",
"model": "plan_has_goal",
"foreignKey": "plan_has_goal_id"
}
},
"acls": [],
"methods": {}
}
{
"name": "plan_has_goal",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"id": {
"type": "number"
},
"activity_id": {
"type": "number"
},
"activity_goal_id": {
"type": "number"
}
},
"validations": [],
"relations": {
"goal": {
"type": "belongsTo",
"model": "activity_goal",
"foreignKey": "activity_goal_id"
},
"actions": {
"type": "hasMany",
"model": "plan_goal_has_action_option",
"foreignKey": "plan_has_goal_id"
}
},
"acls": [],
"methods": {}
}
include and where are two different filters:
{
where: {
activity_id: activity_id
},
include: {
relation: 'planGoal',
scope: {
where: {
activity_goal_id: goal_id
}
}
}
}
in loopback, I started with this model:
[
{
"mov_id": 0,
"mov_tipo": "string",
"mov_valore": 0,
"mov_causale_fk": 0,
"mov_conto_fk": 0,
"mov_data": "2017-10-04T09:02:19.620Z",
"mov_note": "string",
"mov_utente_fk": 0,
"mov_aggiunta": "2017-10-04T09:02:19.620Z"
}
]
then I added two relations, which correspond to two Foreign Keys in my MySQL database:
"relations": {
"causale_fk": {
"type": "hasOne",
"model": "causali",
"foreignKey": "causale_id",
"options": {
"nestRemoting": true
}
},
"conto_fk": {
"type": "hasOne",
"model": "conti",
"foreignKey": "conto_id",
"options": {
"nestRemoting": true
}
}
},
I would also like to see the fields in those models, as if I did make a query with JOIN.
it's possible??
ok, i resolved with scope.
this is the model:
{
"name": "movimenti",
"plural": "movimenti",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"scope": {
"include": [
"causale_fk",
"conto_fk"
]
},
"properties": {
"mov_id": {
"type": "number",
"id": true,
"required": true
},
"mov_valore": {
"type": "number",
"required": true
}
},
"validations": [],
"relations": {
"causale_fk": {
"type": "hasOne",
"model": "causali",
"foreignKey": "causale_id"
},
"conto_fk": {
"type": "hasOne",
"model": "conti",
"foreignKey": "conto_id",
"include": "conti"
}
},
"acls": [],
"methods": {}
}
bye!!
You can your to add options in your filter, and the particular option you need to set is include. Check here for more details.
This is an example for you particular needs:
{
Model.find({include:['causale_fk','conto_fk']}, function(){});
}