JSON schema - new sub schema based on a property - javascript

I wanted a JSON schema that could have 3 fields: num, key1, and key2. Both num and key1 are mandatory fields. The field key2 is mandatory ONLY WHEN the key1 was provided a value of 'abc'. Here is the schema that I have created:
schema = {
type: 'object',
additionalProperties: false,
properties: {
num: {
type: 'number',
minimum: 1,
maximum: 5
},
key1: {
type: 'string',
enum: ['abc', 'def']
}
},
required: ['num', 'key1'],
if: {
properties: {
key1: {
const: 'abc'
}
}
},
then: {
properties: {
key2: {
type: 'string',
required: true
}
}
}
};
Here is the instance that I want to validate against the schema using npm module jsonscehma ("jsonschema": "^1.2.0"):
instance = {
num: 1,
key1: 'abc'
};
var Validator = require('jsonschema').Validator;
var v = new Validator();
console.log(v.validate(instance, schema));
My expectation here is that, since the value of key1 is 'abc', this should ideally throw an error saying
mandatory field "key2" is missing
But, there is no such error in this case.
Also, if I provide key2 in the instance, I am getting
additionalProperty "key2" exists in instance when not allowed
even though, key1 is 'abc'.
Please specify if I have missed anything here.

The library you're using only supports draft-04 of the specification.
if / then / else wasn't added till draft-07.

Related

How to validate object constraint in a object using joi?

I am trying object validation with the help of joi.
I want to validate object as a constraint inside an object like
let login = {
value: 0/1,
slots: [{ label: '', value: '24 hr'}, { label: '', value: '24 hr'}]
}
Here login is an object and inside it slots is also an object. So if I write like the following
const schema = Joi.object().keys({
value : Joi.number.required(),
slots : Joi.string.required()
});
would it be correct for object data type or should I replace string data type with object data type?
I want to validate object type as a constraint.
Your slots key needs to be an array of objects:
const schema = Joi.object().keys({
value: Joi.number().required(),
slots: Joi.array().items(
Joi.object().keys({
label: Joi.string().required().allow(''),
value: Joi.string().required()
})
)
})
This way, the following object will be valid:
const obj = {
value: 1,
slots: [
{
label: '',
value: '24 hr'
}
]
}

not able to validate array of objects correctly using is-my-json-valid npm module

I am using is-my-json-valid npm module to validate incoming http request. I defined schema to validate array of objects . This npm module failed to validate objects inside array correctly.
I have defined the schema as mentioned below:
var validator = require('is-my-json-valid')
var validate = validator({
required: true,
type: 'object',
properties: {
name: {
required: true,
type: 'string'
},
author: {
required: true,
type: 'string'
},
libraries: {
required: true,
type: 'array',
items: {
type: 'object',
properties: {
id: {
required: true,
type: 'number'
}
},
additionalProperties: false
}
}
},
additionalProperties: false
});
const obj = {
name: 'myn4m3',
author: 'mys3lf',
libraries: []
};
console.log('should be valid', validate(obj));
// console.log('should not be valid', validate({}))
console.log(validate.errors)
Actual:
should be valid true
null
Expected:
since, libraries array had mandatory "id" property as i'm not providing it it should throw validation error but it gives true.
can someone help on this ?
You need to add Objects in array
change this
const obj = {
name: 'myn4m3',
author: 'mys3lf',
libraries: []
};
to this
const obj = {
name: 'myn4m3',
author: 'mys3lf',
libraries: [{}]
};

Realm - Value not convertible to a number

Hello community :) I implemented lots of good working functionality with firebase -> realm. Now i tried to edit a structure and I am running through the wildest error messages.
What is right for sure:
Firebase sends the data
Data is Converted (e.g. Firebase has "brands" as array -> is converted to a string for Realm Schema)
The error appears when firebase updates
Not every firebase content has all fields (e.g. Like you can see out of Realm Schema some fields are optional: true)
Fields where i maybe expect an issue:
Maybe its not possible to say that the ReferentList is optional (or i implemented it wrong): See Realm Schema const ReferentsList
What i tried
Debug before realm.create (Realm set) Result: Every data came in the right format
Checked all input values if they are int, string, ...
Hopefully someone can help me here because i got completely stuck with this issue and its necesarry to continue for my project. I want to know:
The solution why or what to do
A posibility to debug realm in a better way
Thank you in advance for your time and help :)
Error message: Value not convertible to a number
Firebase datastructure
"begin" : "2017-05-15T15:50:00.000Z",
"description" : "abc",
"end" : "2017-05-15T16:15:00.000Z",
"id" : 6,
"language" : [ 1 ],
"location" : "L 1.02",
"member" : 20,
"referent" : [ 1, 3 ],
"register" : true,
"title" : "Sound of Silence",
"track" : 6,
"type" : 3,
"brands" : [ 1, 2, 3 ]
Realm Schema
const ReferentListSchema = {
name: 'ReferentList',
properties: {
id: {
type: 'int',
optional: true
}
}
}
const LanguageListSchema = {
name: 'LanguageList',
properties: {
id: 'int'
}
}
const EventSchema = {
name: 'Events',
primaryKey: 'id',
properties: {
id: 'int',
begin: {
type: 'date',
optional: true
},
end: {
type: 'date',
optional: true
},
title: 'string',
description: 'string',
register: 'bool',
member: {
type: 'int',
optional: true
},
language: {
type: 'list',
objectType: 'LanguageList'
},
location: 'string',
referent: {
type: 'list',
objectType: 'ReferentList'
},
type: 'int',
track: {
type: 'int',
optional: true
},
img: {
type: 'string',
optional: true
},
brands:{
type: 'string',
optional: true
}
}
}
Realm set
set(obj) {
realm.write(() => {
if(obj.referent){
obj.referent = obj.referent.map(function(id) {
return {id};
})
}
if (obj.language){
obj.language = obj.language.map(function(id) {
return {id};
})
}
realm.create('Events', obj, true);
});
}
Solved:!
The issue got solved through wrong data at firebase. Some Date Objects hasent been set correct.
How i got to the solution
When i tried to debugg the code i made a try/catch block around:
try{
realm.create('Events', obj, true);
}catch(error){
console.log(obj);
console.log(error);
}
Through this debug i found the right data wich was wrong. Before it just showed me all objects and afterwards the error.
I wont close this question because of the chance to help someone with the same issues.-

Make a new object from an array of objects [duplicate]

This question already has answers here:
Create an object with dynamic property names [duplicate]
(2 answers)
Closed 6 years ago.
This is possibly a duplicate, but everywhere I search I can only seem to find people wanting to create an array of objects.
Basically I'm trying to achieve the opposite, pull certain values of an array of objects out into an object. It's twisting my head a little so any of you JS gurus out there if you could give me a hand it would be very very appreciated!
Basically I have an array of objects like this:
[
{ field: 'name', value: 'sam', isRequired: true },
{ field: 'email', value: 'sam#dummyemail.net', isRequired: true },
{ field: 'message', value: 'hey', isRequired: false },
]
They're split up this way because I go through the fields for validation.
After the validation phase I want to map the field and value properties to name value pairs within a new object e.g:
{
name: 'sam',
email: 'sam#dummyemail.net',
message: 'hey',
}
Like I said any help would be amazing! Cheers.
Array#map each object in the array into a new object with field as the key of a property, and value, well, the value of the property. Then combine the new objects array to object using the spread syntax and Object#assign:
const arr = [
{ field: 'name', value: 'sam', isRequired: true },
{ field: 'email', value: 'sam#dummyemail.net', isRequired: true },
{ field: 'message', value: 'hey', isRequired: false },
];
const result = Object.assign({}, ...arr.map(({ field, value }) => ({ [field]: value })));
console.log(result);
you could map array into object like this
var array = [
{ field: 'name', value: 'sam', isRequired: true },
{ field: 'email', value: 'sam#dummyemail.net', isRequired: true },
{ field: 'message', value: 'hey', isRequired: false },
];
var object = {};
array.forEach(x => {
object[x.field] = x.value;
});
console.log(object);

need javascript array format

I am looking to create following format in array in javascript.
Each item has:
url -> string (which is login URL)
name -> string
inputs -> array
And each input is:
name -> string
type -> string
value -> string
Please guide me , how to do this in JavaScript
[
{url: 'http://google.com/',
name: 'google',
inputs: [
{ name: 'search-term', type: 'string', value: 'javascript' },
{ name: 'region', type: 'country-code', value: 'IN' }
]
},
{url: 'http://yahoo.com/',
name: 'yahoo',
inputs: [
{ name: 'search-term', type: 'string', value: 'javascript' },
{ name: 'region', type: 'country-code', value: 'US' }
]
}
]
there you go.
on a related note, JSON might be worth looking at once. Though I must say, the above is not json, only json-like.
This would be tricky in a strongly typed language like Java or C#, but it's pretty easy in JavaScript.
Since JavaScript doesn't have strong typing for array values and variables, you can just create an array of object literals. Each object would contain the properties you specified. There's no need to specify the string type on each property--JavaScript will infer that for you.
While this is really easy to do, the drawback is that you're not going to get any type checking, so some code could inadvertently stick an object into one of your string fields and JavaScript won't stop it.
So just beware of the advantages and disadvantages of JavaScript's flexibility, and make sure you're doing server-side sanity checks on your data.
var items =
[
{
url: "http://...",
name: "FOO",
inputs: [
{
name: "Input1",
type: "LeTypeh"
value: "Levalueh"
},
{
name: "Input2 (Foo)",
type: "LeType2a",
value: "Levalue2j"
}
// ... (insert as many comma separated inputs as you need in the foo item
},
{
url: "http://...",
name: "BAR",
inputs: [
{
name: "Input1",
type: "LeTypeh"
value: "Levalueh"
},
{
name: "Input2 (Bar)",
type: "LeType2a",
value: "Levalue2j"
}
// ... (insert as many comma separated inputs as you need in the bar item here
}
//... (insert as many comma separated items as you need in the array here
]

Categories