jsonschema not throwing error on missing required property - javascript

I have the following schema:
const LIST_EVENTS = {
"id": "/listEvents",
"type": "object",
"properties": {
"filter": {
"$ref": "/MarketFilter",
"required": true
},
"locale": {
"type": "string"
}
}
}
From debugging, I can see that the object being sent to the validation is:
{
marketFilter: {
eventTypeIds: [ '1' ],
marketStartTime: {
from: '2018-12-15T00:00:00+00:00',
to: '2018-12-15T23:59:59+00:00'
}
}
}
marketFilter does not match the name of filter in the schema. To my understanding, seeing as this is a required property, this should have been flagged in the errors array of the validation result but it is not. This is my validation result:
ValidatorResult {
instance:
{ marketFilter: { eventTypeIds: [Array], marketStartTime: [Object] } },
schema:
{ id: '/listEvents',
type: 'object',
properties: { filter: [Object], locale: [Object] } },
propertyPath: 'instance',
errors: [],
throwError: undefined,
disableFormat: false }
I thought that it was possible that it did not mind about the naming convention so I removed the property altogether and still, an error is not logged with this being the validation result:
ValidatorResult {
instance: {},
schema:
{ id: '/listEvents',
type: 'object',
properties: { filter: [Object], locale: [Object] } },
propertyPath: 'instance',
errors: [],
throwError: undefined,
disableFormat: false }
I have many schemas and they are all added via .addSchema method

You have two issues with your schema. The main issue is that your required keyword is ignored because it is next to $ref. When an object with a $ref keyword is encountered where a schema is expected, it's treated as a JSON Reference only. It's not treated as a schema. A JSON Reference only has semantics for the $ref keyword. Everything else is ignored. You could fix your problem by isolating the $ref in you schema.
"filter": {
"allOf": [{ "$ref": "/MarketFilter" }],
"required": true
}
The other problem is the use of the boolean form of the required keyword. This usage of the required keyword was removed from the JSON Schema specification years ago. Unless you are specifically writing JSON Schemas against the draft-03 specification (unlikely, it's long out of date), you should be using the array form of required. Some older implementations allow you to use both forms, but that's not a good idea. You should be targeting a single specification and not mix keywords from two different versions of specification.
{
"id": "/listEvents",
"type": "object",
"properties": {
"filter": {
"$ref": "/MarketFilter"
},
"locale": {
"type": "string"
}
},
"required": ["filter"]
}

For now, I have found a work-around that is also described in the docs. I have added the required array property to the schema and added filter to it. This now threw an error.
However, the documentation states that the required property on the property itself should work the same. Is this potentially an issue with the package or is there different behaviours if the property is a reference?

Related

How to search for specific word and exact match in ElasticSearch

sample data for title
actiontype test
booleanTest
test-demo
test_demo
Test new account object
sync accounts data test
default Mapping for title
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
tried with this query search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": "test"
}
}
]
}
},
}
here my expectation
with specific word(e.g. : test ) it should return following titles
expect
actiontype test
booleanTest
test-demo
test_demo
Test new account object
sync accounts data test
But
got
actiontype test
test-demo
test_demo
Test new account object
sync accounts data test
With exact match (e.g. : sync accounts data test ) it should return only this(sync accounts data test) but got all records those contains this words (sync,account,data,test).
What should I do to make this happen ? Thanks.
I am not sure which ES version you're using but the following should give you an idea.
Using your mapping you can get all title text with test, including booleanTest using query string query type. Eg.
GET {index-name}/{mapping}/_search
{
"query": {
"query_string": {
"default_field": "title",
"query": "*test*"
}
}
}
However, for this to work, make sure you give your title field an analyzer with a lowercase analyzer filter (see below settings example). Your current mapping will not work since it's just pure text as is... test /= TEST by default.
There are other ways, if you're interested to know the workings of ES... Eg. You can also match booleanTest in your match query by writing a custom nGram filter to your index settings. Something like,
{
"index": {
"settings": {
"index": {
"analysis": {
"filter": {
"nGram": {
"type": "nGram",
"min_gram": "2",
"max_gram": "20"
}
},
"ngram_analyzer": {
"filter": [
"lowercase",
"nGram"
],
"type": "custom",
"tokenizer": "standard"
}
}
}
}
}
}
NB: ngram_analyzer is just a name. You can call it whatever.
min_gram & max_gram: Pick numbers that work for you.
Learn more about n-gram filter, the goods and bad here: N-GRAM
Then you can add the analyzer to your field mapping like,
{
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256,
"analyzer": "ngram_analyzer"
}
}
}
}
Lastly for exact matches, these work on type keyword. So based on your mapping, you already have the keyword field so you can use term query to get the exact match by searching on the title.keyword field;
GET {index-name}/{mapping}/_search
{
"query": {
"term": {
"title.keyword": {
"value": "sync accounts data test"
}
}
}
}
Also, you will want to read/ learn more about these solutions and decide on the best solution based on your indexing setup and needs. Also, there may be more ways to achieve what you need, this should be a good start.

Invalid configuration for rule "react/jsx-sort-props"

I'm trying to sort props names alphabetically using the plugin eslint-plugin-react but I'm getting this error:
[Error ] .eslintrc.json: Configuration for rule "react/jsx-sort-props" is invalid: Value {"callbacksLast":true,"shorthandFirst":false,"shorthandLast":true,"multiline":"last","ignoreCase":true,"noSortAlphabetically":false} should NOT have additional properties.
This is my .eslintrc.json file:
{
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"next/core-web-vitals"
],
"rules": {
"react/jsx-sort-props": [
"2",
{
"callbacksLast": true,
"shorthandFirst": false,
"shorthandLast": true,
"multiline": "last",
"ignoreCase": true,
"noSortAlphabetically": false
}
]
}
}
What I'm missing?
There are two issues:
The severity option, if you're using a number, should be a number, not a string that contains a number - 2, not "2". (Though, personally, I'd suggest using "error" instead - it makes it clearer from reading the config what the rule means for your project - "error" makes more intuitive sense than 2)
There is a bug in the linter rule's jsx-sort-props.js - although the docs reference a multiline property, said property does not exist anywhere in the lint rule implementation, and so an error is thrown when you pass in an object containing that property. Remove it.
"rules": {
"react/jsx-sort-props": [
2,
{
"callbacksLast": true,
"shorthandFirst": false,
"shorthandLast": true,
"ignoreCase": true,
"noSortAlphabetically": false
}
]
}

Swagger: first enum value overwrites type

I am using swagger doc to generate API for my app. Doc is written in yml and in some place it is going to define some props which are enum (we use mysql). This is looks like:
properties:
type:
enum:
- "first"
- "second"
- "example"
type: "string"
title:
type: "string"
... // And so on and on
I am expecting to get something like this:
{
"type": "string",
"title": "string",
}
As you can see, type field is going to be a string as was defined in config file, but I am receiving this one instead:
{
"type": "first",
"title": "string",
}
Swagger sets first value as a data type and it is absolutely incorrect.
So the question is how to get value "string" for "type" field.
I have been writing my swagger documentation in JSON. Below is an example of how I have my "enums" set up. Maybe you can translate it to YML to get a better idea.
"parameters":[
{
"name":"userID",
"in":"path",
"description":"TO BE DETERMINED.",
"required":true,
"type":"string"
},
{
"name":"embedded",
"in":"query",
"description":"TO BE DETERMINED",
"required":false,
"type":"array",
"items":{
"enum":[
"address",
"state"
]
},
"collectionFormat":"csv"
}
If you look at items you see that I don't use a type and it works fine.

AngularJS - parsing JSON feed with namespace

New to angular, and it is awesome.
One thing I am having a brain fart on is parsing a JSON feed that contains namespaces:
Example from JSON feed:
"title": {
"label": "Fuse"
},
"im:name": {
"label": "John Doe"
},
"im:image": [ {
"label": "70x70",
"attributes": {
"height": "55"
}
}, {
"label": "80x80",
"attributes": {
"height": "60",
"im:link": "www.google.com"
}
}, {
"label": "90x90",
"attributes": {
"height": "170"m
"im:link": "www.yahoo.com"
}
}],
I can successfully parse items without namespaces fine like so:
<p ng-repeat="item in results.feed['entry']">
title: {{item.title['label']}}
</p>
But cannot get the items with namespaces to display using:
name: {{item.['im:name']['label']}}
OR
name: {{item.['im-name']['label']}}
OR
name: {{item.['im->name']['label']}}
Since being a newbie, I thought something like this would work:
<div xmlns:im="http://www.aol.com" id="im-app" im-app="im">
<p ng-repeat="item in results.feed['entry']">
…namespace code in here…
</p>
</div>
But that did not help.
Extra bonus question: What if a namespace contains attributes, that also contain namespaces?
Any help would greatly be appreciated.
Thanks!
Roc.
Although Craig answered the question,
This is also for reference for others:
If you want to target a specific key inside of an object set:
"im:image":[
{
"label":google",
"attributes":{
"height":"55"
}
},
{
"label":"yahoo",
"attributes":{
"height":"60"
}
},
{
"label":"aol",
"attributes":{
"height":"170"
}
}
{{item['im:image'][2]['label']}}
Will get the 3rd key in that set.
Thanks.
Get rid of the dot after item
Working example: http://jsfiddle.net/bonza_labs/Kc2uk/
You access the properties exactly the same way as straight javascript (because angular is basically eval()-ing the expression as javascript**). item.['foo'] is not valid javascript. You are correct in using square-bracket notation as my:name is not valid for dot-notation.
valid:
item.foo
item['foo']
with non-standard property names:
item['foo:bar']
item['foo-bar']
and in your case:
{{item['im:name']['label']}}
** or close enough for understanding this solution

Backbone relational with key in nested attribute

I am using Backbone-relational to have relational models. But i'm having a problem with related models of which the keys are in a nested attribute.
My model looks like this:
Event.Model = Backbone.RelationalModel.extend({
urlRoot: "/events",
defaults: {
"id": null,
"title": {
"en": "Event name"
},
"related": {
"actions": {}
"resources": {
"production": production_id
}
}
},
relations: [
{
type: Backbone.HasOne,
key: "related.resources.production",
relatedModel: Production.Model,
relatedCollection: Production.Collection,
autoFetch: true
}
]
});
What i am trying to achieve is: turn the Event.Model.related.resources.production into a Production.Model. The code above does not work.
When i fix it by implementing a Event.Model#parse() which takes Event.Model#related.resources.production and moves that to Event.Model#production, and i set the key in the "relations" to "production", it does work. But this seems like a really hacky solution.
Does this mean Backbone-relational doesn't understand the dotNotation in the key? Or am i doing something wrong?

Categories