AJV validate string against an array of objects - jsonschema

I'm trying to use AJV to check that parent_IDs on child objects are valid IDs on the parent objects.
I can get it to work by validating against a single parent object like this:
const ajv = new Ajv({
$data: true,
allErrors: true,
verbose: true,
});
addFormats(ajv, ["uuid"]);
const schema = {
type: "object",
properties: {
parentObjects: {
type: "array",
items: {
type: "object",
properties: {
id: { type: "string", format: "uuid" },
name: { type: "string" },
},
required: ["id", "name"],
},
},
childObjects: {
type: "array",
items: {
type: "object",
properties: {
id: { type: "string", format: "uuid" },
name: { type: "string" },
parent_id: {
type: "string",
format: "uuid",
const: { $data: "/parentObjects/0/id" },
},
},
required: ["id", "name", "parent_id"],
},
},
},
};
const data = {
parentObjects: [
{
id: "3bc169ba-99c4-448a-8c22-5c2593ccc9ee",
name: "larry",
},
{
id: "d2e92e51-cb56-4451-bf8b-349d82fde107",
name: "curly",
},
{
id: "b99f61f5-f417-4129-9315-ab049d2b618d",
name: "moe",
},
],
childObjects: [
{
id: "bd86603f-fb1d-4075-94f5-619337d43b98",
name: "stan",
parent_id: "3bc169ba-99c4-448a-8c22-5c2593ccc9ee",
},
{
id: "c2b80273-bf2b-4898-a44b-a758a436cb37",
name: "oliver",
parent_id: "e13b7c34-6cb5-4ef4-83a7-7d11c2bd4a1f",
},
],
};
ajv.validate(schema, data);
console.log(ajv.errors);
};
But what I need is to be able to validate against all parent objects, something like:
childObjects: {
type: "array",
items: {
type: "object",
properties: {
id: { type: "string", format: "uuid" },
name: { type: "string" },
parent_id: {
type: "string",
format: "uuid",
enum: { $data: "/parentObjects/*/id" },
},
},
required: ["id", "name", "parent_id"],
},
},
I can't find a way to use a wildcard for the array index "/parentObjects/*/id" or a way to iterate through all of the parentObjects. I could map the parentObject IDs outside of AJV, create another array and validate against that, but it seems like overkill - I feel like I'm missing something simple in AJV which would allow me to do this without generating a new array.

Related

How can i make nested schema for a course with sub-topic and every sub-topic having Sub-topic Name, time duration, video URL in Sanity.io?

**
I don't Know how to make this please help if possible or tell me where can i find some similar Schema
I want to create video lecturer website
with topic, sub-topic, time-duration
**
export default {
name: "Courses",
title: "Property",
type: "document",
fields: [
{
title: "Movie",
name: "movie",
type: "document",
fields: [
{
title: "Title",
name: "title",
type: "string",
},
{
title: "Poster",
name: "poster",
type: "image",
},
{
title: "Sub-Topic",
name: "directors",
type: "array",
of: [{ type: "string" }],
},
{
title: "Video URL",
name: "imageUrl",
type: "url",
},
{
title: "Rich text example",
name: "myRichTextExample",
type: "array",
of: [{ type: "block" }],
},
],
},

How to display list of data in a column in iview table

In iview table, my colums:
export default {
data () {
return {
columns5: [
{
title: 'CNAME',
key: 'name',
sortable: true
},
{
title: 'nodes',
key: 'nodes',
},
{
title: 'domains',
key: 'domains',
},
{
title: 'desc',
key: 'desc'
},
{
title: 'duetime',
key: 'duetime',
sortable: true
},
{
title: 'ctime',
key: 'ctime',
sortable: true
},
{
title: 'uptime',
key: 'uptime',
sortable: true
},
],
the data:
anames:[
{
"id": 1,
"nodes": [
{
"id": 1,
"main_ip": "10.10.10.10",
"ips": "10.10.10.10\r\n10.10.10.11",
"req_secret": null,
"ctime": "2021-05-17T09:41:53.159131+08:00",
"uptime": "2021-05-17T10:31:47.886033+08:00",
"cname": 1
}
],
"domains": [
{
"id": 1,
"domain_name": "baidu.com",
"ctime": "2021-05-17T16:19:18.097807+08:00",
"uptime": "2021-05-17T16:19:18.097955+08:00",
"cname": 1
}
],
"name": "masdcom",
"desc": "",
"desc_en": null,
"is_active": true,
"duetime": "2021-06-17T19:40:00+08:00",
"ctime": "2021-05-17T09:13:57.019125+08:00",
"uptime": "2021-05-17T19:42:23.025122+08:00",
"user": 2
}
]
You see my nodes and domains,in data anames they are list, not just key-value, how can I display domain's domain_name and node's main_ip?
In there can not use domains.domain_name and nodes.main_ip.
I want nodes display all node's main_ip and domains display all domain's domain_name. what should I do in columns?
domains and nodes is array, you forgot about indexes
domains[0].domain_name and nodes[0].main_ip

Can I have a JSON Schema dependency that adds a field inside an array of objects?

I have a JSON Schema that includes an array of objects. I'd like one of the fields inside those objects to be dependent on a property outside the array.
I created the following schema:
{
type: "object",
properties: {
showNotes: {
title: "Add notes field",
type: "boolean",
},
choices: {
type: "array",
title: "Choices",
items: {
type: "object",
properties: {
itemName: {
type: "string",
title: "Item"
},
isRequired: {
type: "boolean",
title: "Required?",
default: false
},
note: {}
}
},
default: [
{
content: "Thing 1",
correct: false
}
]
}
},
dependencies: {
showNotes: {
oneOf: [
{
properties: {
showNotes: {
enum: [
false
]
}
}
},
{
properties: {
showNotes: {
enum: [
true
]
},
note: {
title: "Note",
type: "string"
}
}
}
]
}
}
}
I was hoping that the new field note would update the one at items/note, but it did not, instead it generated a new field note at the bottom. This can be seen here:
https://codepen.io/samfentr/pen/ZEQpeyg
I assume that the solution will have something to do with adding $ref reference, but I haven't been able to work it out.
I was able to solve this.
I needed to put the entire path to notes in my oneOf option:
showNotes: {
oneOf: [
{
properties: {
showNotes: {
enum: [
false
]
}
}
},
{
properties: {
showNotes: {
enum: [
true
]
},
choices: {
items: {
properties: {
note: {
type: "string",
title: "Note"
}
}
}
}
}
}
]
}
https://codepen.io/samfentr/pen/BajQwYE

extjs 4 - Unable to expand a dynamically generated tree

I have a requirement to create a tree grid which has unknown number of columns and data which gets rendered on click on a button. I have following code for the same.
//Model
Ext.define('SM.model.DynamicTreeModel', {
extend: 'Ext.data.Model'
});
//Store
Ext.define('SM.store.DynamicTreeStore',{
extend:'Ext.data.TreeStore',
model:'SM.DynamicTreeModel',
root: {
expanded: true
},
proxy: {
type: 'ajax',
url: 'TGData1.json',
reader: {
type: 'json',
root: 'children'
}
},
autoLoad: true
});
Ext.define('SM.view.compareScenario.DynamicTree', {
extend: 'Ext.tree.Panel',
alias: 'widget.DynamicTree',
frame: true,
columnLines: true,
autoLoad: false,
initComponent: function(){
var config = {
columns: [],
rowNumberer: false
};
Ext.apply(this, config);
Ext.apply(this.initialConfig, config);
this.callParent(arguments);
},
storeLoad: function(){
var columns = [];
Ext.each(this.store.proxy.reader.jsonData.columns, function(column){
columns.push(column);
});
this.reconfigure(this.store, columns);
this.store.getRootNode(this.store.getRootNode);
},
onRender: function(ct, position){
SM.view.compareScenario.DynamicTree.superclass.onRender.call(this, ct, position);
this.store.load({
scope: this,
callback: function(records, operation, success) {
this.storeLoad();
}
});
}
});
var influencesTree = {
xtype: 'DynamicTree',
id: 'influencesTree',
pading: '5',
region: 'south',
height: '70%',
collapsible: true,
rootVisible: false,
store: 'DynamicTreeStore'
};
The json file is as follows:
{
"metaData": {
"fields": [
{"name":"0", "type":"string"},
{"name":"1", "type":"string"},
{"name":"2", "type":"string"}
]
},
"columns" : [
{
"xtype":"treecolumn", //this is so we know which column will show the tree
"text":"Override Type",
"flex":"2",
"sortable":"true",
"dataIndex":"0"
},
{
"text":"Scenario 1",
"dataIndex":"1"
},
{
"text":"Copied Scenario",
"dataIndex":"2"
}
]
,
"text": ".",
"children": [{
"0":"CFO",
"1":"15",
"2":"16",
"children":[{
"0":"AW",
"1": "5",
"2": "5",
"leaf": "true",
},
{
"0":"AV",
"1":"10",
"2":"11",
"leaf": "true",
}
]
}
]
}
The tree renders, but the child nodes cannot be expanded as the + icon is not shown. Instead of + icon, a checkbox is rendered.
Any help/suggestions for the same will be highly appreciated.
Thanks,
Shalini
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.dd.*']);
Ext.onReady(function () {
var myData = [{
name: "Rec 0",
type: "0"
}, {
name: "Rec 1",
type: "1"
}, {
name: "Rec 2",
type: "2"
}, {
name: "Rec 3",
type: "3"
}, {
name: "Rec 4",
type: "4"
}, {
name: "Rec 5",
type: "5"
}, {
name: "Rec 6",
type: "6"
}, {
name: "Rec 7",
type: "7"
}, {
name: "Rec 8",
type: "8"
}, {
name: "Rec 9",
type: "9"
}];
// create the data store
var firstGridStore = Ext.create('Ext.data.Store', {
model: 'Apps.demo.model.Resource',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/echo/json/',
actionMethods: {
read: 'POST'
},
extraParams: {
json: Ext.JSON.encode(myData)
},
delay: 0
}
});
// Column Model shortcut array
var columns = [{
text: "Name",
flex: 1,
sortable: true,
dataIndex: 'name'
}, {
text: "Type",
width: 70,
sortable: true,
dataIndex: 'type'
}];
// declare the source Grid
var firstGrid = Ext.create('Ext.grid.Panel', {
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
ddGroup: 'selDD'
},
listeners: {
drop: function (node, data, dropRec, dropPosition) {
}
}
},
store: firstGridStore,
columns: columns,
stripeRows: true,
title: 'First Grid',
margins: '0 2 0 0'
});
// create the destination Grid
var secondTree = Ext.create('Apps.demo.view.TreeGrid', {
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
ddGroup: 'selDD'
},
listeners: {
beforedrop: function (node, data) {
data.records[0].set('leaf', false);
data.records[0].set('checked', null);
},
drop: function (node, data, dropRec, dropPosition) {
firstGrid.store.remove(data.records[0]);
}
}
}
});
var displayPanel = Ext.create('Ext.Panel', {
width: 650,
height: 300,
layout: {
type: 'hbox',
align: 'stretch',
padding: 5
},
renderTo: 'panel',
defaults: {
flex: 1
}, //auto stretch
items: [
firstGrid,
secondTree],
dockedItems: {
xtype: 'toolbar',
dock: 'bottom',
items: ['->', // Fill
{
text: 'Reset both components',
handler: function () {
firstGridStore.loadData(myData);
secondTreeStore.removeAll();
}
}]
}
});
});
var response = Ext.JSON.encode({
"children": [{
"itemId": 171,
"type": "comedy",
"name": "All the way",
"children": [{
"leaf": true,
"itemId": 171,
"type": "actor",
"name": "Rowan Atkinson"
}],
}, {
"itemId": 11,
"type": "fantasy",
"name": "I love You",
"children": [{
"itemId": 11,
"leaf": true,
"type": "actor",
"name": "Rajan",
}]
}, {
"itemId": 173,
"type": "Action",
"name": "Fast and Furious",
"children": [{
"itemId": 174,
"type": "actor",
"name": "Dwayne Johnson",
"children": [{
"leaf": true,
"itemId": 175,
"type": "wrestler",
"name": "The Rock"
}]
}]
}]
});
Ext.define('Apps.demo.model.Resource', {
extend: 'Ext.data.Model',
fields: [{
name: "name",
type: "string"
}, {
name: "type",
type: "string"
}]
});
Ext.define('Apps.demo.view.TreeGrid', {
extend: 'Ext.tree.Panel',
title: 'Demo',
height: 300,
rootVisible: true,
singleExpand: true,
initComponent: function () {
Ext.apply(this, {
store: new Ext.data.TreeStore({
model: 'Apps.demo.model.Resource',
"root": {
"name": "",
"type": "",
"expanded": "true"
},
proxy: {
type: 'ajax',
url: '/echo/json/',
actionMethods: {
read: 'POST'
},
extraParams: {
json: response
},
delay: 0
}
}),
listeners: {
'beforeiteminsert' : function(obj, node) {
console.log(node);
}
},
columns: [{
xtype: 'treecolumn',
text: 'Name',
dataIndex: 'name',
width: 200
}, {
text: 'Type',
dataIndex: 'type'
}]
});
this.callParent();
}
});
var grid = Ext.create('Apps.demo.view.TreeGrid');
Please check this code .It might not give u the proper answer but will surely give u the hint how to achieve the output.

Complex array at QML

I got in trouble with very simple code:
property var pagesAllModels: {
ru: [
{ title: qsTr("New"), url: "http://bash.im" },
{ title: qsTr("Random"), url: "http://bash.im/random" },
{ title: qsTr("Best"), url: "http://bash.im/best" },
{ title: qsTr("By rating"), url: "http://bash.im/byrating" },
{ title: qsTr("Abyss"), url: "http://bash.im/abyss" },
{ title: qsTr("Abyss top"), url: "http://bash.im/abysstop" },
{ title: qsTr("Abyss best"), url: "http://bash.im/abyssbest" },
],
eng: [
{ title: "Latest", url: "http://bash.org/?latest" },
{ title: "Browse", url: "http://bash.org/?browse" },
{ title: "Random", url: "http://bash.org/?random" },
{ title: "Top", url: "http://bash.org/?top" }
]
}
That code in QML gives me error at line "eng: [" with error "expected lexem ," but in pure javascript everything work fine. What's wrong?
That's because your code is illegal JSON array definition. Web browsers are accepting it because they aren't strict about JS syntax, but QML engine is really strict :
In a key:value pair in associative array, the key must be a string, so it must have quotes around it, else it would be confused with a (non-existing) variable name.
property var pagesAllModels: {
"ru": [
{ "title": qsTr("New"), "url": "http://bash.im" },
{ "title": qsTr("Random"), "url": "http://bash.im/random" },
{ "title": qsTr("Best"), "url": "http://bash.im/best" },
{ "title": qsTr("By rating"), "url": "http://bash.im/byrating" },
{ "title": qsTr("Abyss"), "url": "http://bash.im/abyss" },
{ "title": qsTr("Abyss top"), "url": "http://bash.im/abysstop" },
{ "title": qsTr("Abyss best"), "url": "http://bash.im/abyssbest" }
],
"eng": [
{ "title": "Latest", "url": "http://bash.org/?latest" },
{ "title": "Browse", "url": "http://bash.org/?browse" },
{ "title": "Random", "url": "http://bash.org/?random" },
{ "title": "Top", "url": "http://bash.org/?top" }
]
}
And it works !
Try this
property var pagesAllModels: {
ru: [
{ title: qsTr("New"), url: "http://bash.im" },
{ title: qsTr("Random"), url: "http://bash.im/random" },
{ title: qsTr("Best"), url: "http://bash.im/best" },
{ title: qsTr("By rating"), url: "http://bash.im/byrating" },
{ title: qsTr("Abyss"), url: "http://bash.im/abyss" },
{ title: qsTr("Abyss top"), url: "http://bash.im/abysstop" },
{ title: qsTr("Abyss best"), url: "http://bash.im/abyssbest" }
],
eng: [
{ title: "Latest", url: "http://bash.org/?latest" },
{ title: "Browse", url: "http://bash.org/?browse" },
{ title: "Random", url: "http://bash.org/?random" },
{ title: "Top", url: "http://bash.org/?top" }
]
}
Hope this will resolve your issue
associative arrays separates by semicolon ";"
Try this
property var pagesAllModels: {
ru: [
{ title: qsTr("New"), url: "http://bash.im" },
{ title: qsTr("Random"), url: "http://bash.im/random" },
{ title: qsTr("Best"), url: "http://bash.im/best" },
{ title: qsTr("By rating"), url: "http://bash.im/byrating" },
{ title: qsTr("Abyss"), url: "http://bash.im/abyss" },
{ title: qsTr("Abyss top"), url: "http://bash.im/abysstop" },
{ title: qsTr("Abyss best"), url: "http://bash.im/abyssbest" },
];
eng: [
{ title: "Latest", url: "http://bash.org/?latest" },
{ title: "Browse", url: "http://bash.org/?browse" },
{ title: "Random", url: "http://bash.org/?random" },
{ title: "Top", url: "http://bash.org/?top" }
]
}