Our school receives data from a source during a sync.
I'm familiar with JavaScript but would like to ask for a litle help before I make a change.
Here is the scenario: The source sending the information to us has the default value as "tobedeleted". We need this to be translated to "inactivate". and then put into our DB.
What's being sent I think is simply ignored because it doesn't match any of our enum values.
My idea is to get help writing: if the get value = "tobedeleted" then translate it to "inactivate" and then update our database.
{
"path": "/v1/courses/{course_id}/enrollments/{id}",
"description": "Conclude, deactivate, or delete an enrollment. If the +task+ argument isn't given, the enrollment\nwill be concluded.",
"operations": [
{
"method": "DELETE",
"summary": "Conclude, deactivate, or delete an enrollment",
"notes": "Conclude, deactivate, or delete an enrollment. If the +task+ argument isn't given, the enrollment\nwill be concluded.",
"nickname": "conclude_deactivate_or_delete_enrollment",
"parameters": [
{
"paramType": "path",
"name": "course_id",
"description": "ID",
"type": "string",
"format": null,
"required": true,
"deprecated": false
},
{
"paramType": "path",
"name": "id",
"description": "ID",
"type": "string",
"format": null,
"required": true,
"deprecated": false
},
{
"paramType": "query",
"name": "task",
"description": "The action to take on the enrollment.\nWhen inactive, a user will still appear in the course roster to admins, but be unable to participate.\n(\"inactivate\" and \"deactivate\" are equivalent tasks)",
"type": "string",
"format": null,
"required": false,
"deprecated": false,
"enum": [
"conclude",
"delete",
"inactivate",
"deactivate"
]
}
],
"response_fields": [
],
"deprecated": false,
"deprecation_description": "",
"type": "Enrollment"
}
]
},
Thank you in advance!
Lets assign the JSON to a variable named data. Then you can do
data.operations.map((operation) => {
if (operation.method === 'DELETE') {
operation.parameters.map((param, queryIndex) => {
if (param.paramType === 'query') {
param.enum.map((item, enumIndex) => {
if (item === 'tobedeleted') {
operation.parameters[queryIndex].enum[enumIndex] = 'inactivate';
//item = 'inactivate';
}
});
}
});
}
return operation;
});
Note: This may not be an optimized code but it does the work.
Related
Given:
Say that I am defining a schema for Contacts. But, I can have "Primary Contact", "Student" or one who is both; and different properties that go with all three choices. The contact types are defined in an array of contact_type: [ "Primary Contact", "Student" ] which can be either one, or both.
Say that the fields are as such per contact type:
If Primary Contact, then I want phone_number
If Student, then I want first_name
If Student and Primary Contact then I want phone_number and first_name
Usage
I use Ajv library to validate in Node.js using a code like such:
function validator(json_schema){
const Ajv = require('ajv');
const ajv = new Ajv({allErrors: true});
return ajv.compile(json_schema)
}
const validate = validator(json_schema);
const valid = validate(input);
console.log(!!valid); //true or false
console.log(validate.errors)// object or null
Note: I've had trouble with allErrors: true while using anyOf for this, and I use the output of allErrors to return ALL the missing/invalid fields back to the user rather than returning problems one at a time. Reference: https://github.com/ajv-validator/ajv/issues/980
Schema
I have written the following schema and it works if I do either "Student" or "Primary Contact" but when I pass both, it still wants to validate against ["Student"] or ["Primary Contact"] rather than both.
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
"required": [],
"properties": {},
"allOf": [
{
"if": {
"properties": {
"contact_type": {
"contains": {
"allOf": [
{
"type": "string",
"const": "Primary Contact"
},
{
"type": "string",
"const": "Student"
}
]
}
}
}
},
"then": {
"additionalProperties": false,
"properties": {
"contact_type": {
"type": "array",
"items": [
{
"type": "string",
"enum": [
"Student",
"Primary Contact"
]
}
]
},
"phone": {
"type": "string"
},
"first_name": {
"type": "string"
}
},
"required": [
"phone",
"first_name"
]
}
},
{
"if": {
"properties": {
"contact_type": {
"contains": {
"type": "string",
"const": "Student"
}
}
}
},
"then": {
"additionalProperties": false,
"properties": {
"contact_type": {
"type": "array",
"items": [
{
"type": "string",
"enum": [
"Student",
"Primary Contact"
]
}
]
},
"first_name": {
"type": "string"
}
},
"required": [
"first_name"
]
}
},
{
"if": {
"properties": {
"contact_type": {
"contains": {
"type": "string",
"const": "Primary Contact"
}
}
}
},
"then": {
"additionalProperties": false,
"properties": {
"contact_type": {
"type": "array",
"items": [
{
"type": "string",
"enum": [
"Student",
"Primary Contact"
]
}
]
},
"phone": {
"type": "string"
}
},
"required": [
"phone"
]
}
}
]
}
Example Valid Inputs:
For just ["Primary Contact"]:
{
"contact_type":["Primary Contact"],
"phone":"something"
}
For just ["Student"]:
{
"contact_type":["Student"],
"first_name":"something"
}
For ["Primary Contact", "Student"]
{
"contact_type":["Primary Contact", "Student"],
"phone":"something",
"first_name":"something"
}
Question:
I would like this to validate even if allErrors: true, is this possible? If not, how should I change the schema?
Footnotes
I don't want to change the "contact_type" from being an array unless it is the last resort. (it is a requirement, but can be broken only if there's no other way)
I can't allow any additionalItems, therefore I'm fully defining each object in the if statements although contact_type is common. If I move contact_type out, then I get error messages about passing contact_type as an additionalItem (it looks at the if statement's properties and doesn't see contact_type when it's taken out to the common place). This is why my initial properties object is empty.
Here's how I might go about solving the validation issue: https://jsonschema.dev/s/XLSDB
Here's the Schema...
(It's easier if you try to break up concerns)
{
"$schema": "http://json-schema.org/draft-07/schema",
"type": "object",
First, we want to define our conditional checking subschemas...
"definitions": {
"is_student": {
"properties": {
"contact_type": {
"contains": {
"const": "Student"
}
}
}
},
"is_primay_contact": {
"properties": {
"contact_type": {
"contains": {
"const": "Primary Contact"
}
}
}
}
},
Next, I'm assuming you always want contact_type
"required": ["contact_type"],
"properties": {
"contact_type": {
"type": "array",
"items": {
"enum": ["Primary Contact", "Student"]
}
},
And we need to define all the allowed properties in order to prevent additional properties. (draft-07 cannot "see through" applicator keywords like allOf. You can with draft 2019-09 and beyond, but that's another story)
"phone": true,
"first_name": true
},
"additionalProperties": false,
Now, we need to define our structural constraints...
"allOf": [
{
If the contact is a student, first name is required.
"if": { "$ref": "#/definitions/is_student" },
"then": { "required": ["first_name"] }
},
{
If the contact is a primary contact, then phone is required.
"if": { "$ref": "#/definitions/is_primay_contact" },
"then": { "required": ["phone"] }
},
{
However, additionally, if the contact is both a student and a primary contact...
"if": {
"allOf": [
{ "$ref": "#/definitions/is_student" },
{ "$ref": "#/definitions/is_primay_contact" }
]
},
Then we require both phone and first name...
"then": {
"required": ["phone", "first_name"]
},
Otherwise, one of phone or first name is fine (which one is covered by the previous section)
"else": {
"oneOf": [
{
"required": ["phone"]
},
{
"required": ["first_name"]
}
]
}
}
]
}
I'm not convinced this is the cleanest approach, but it does work for the requirements you've provided.
As for getting validation errors you can pass back to your END user... given the conditional requirements you lay out, it's not something you can expect with pure JSON Schema...
Having said that, ajv does provide an extension to add custom error messages, which given the way I've broken the validation down into concerns, might be useable to add custom errors as you're looking to do (https://github.com/ajv-validator/ajv-errors).
here i have a dynamic json
data = {
"name": "deltha",
"type": "object",
"important": [
"name",
"id",
"number"
],
"information": {
"place": {
"editable": false,
"visible": true
},
"info": {
"type": "object",
"properties": {
"type": {
"visible": true
}
}
},
"Image": {
"required": [
"name"
],
"type": "object",
"properties": {
"deltha": {
"search": "yes"
}
}
}
}
}
here i am trying to check whether each and every nested property has "required" attribute or not
for ex
data['information']["Image"]
here from the above object i have a attribute i have "required" and under that "name" is there
suppose like image how can i check each and every property to check there is 'required' if required there then how can i read that value dynamically
I'll suggest to use a recursive function, here is a working example : stackblitz.com/edit/angular-snucnm
use the hasOwnProperty check the property exist or not
let obj = data['information']["Image"];
if(obj.hasOwnProperty('required')){
console.log(obj.required)
}
you can check the availability of the property as follows,
if (data.information.Image.required !== undefined) {
console.log('prop is defined')
}
How can I validate multicolumn uniqueness in strongloop?
{
"name": "Table1",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"column1": {
"type": "string"
},
"column2": {
"type": "string"
},
"column3": {
"type": "string"
}
},
"validations": [],
"relations": {}
},
"acls": [],
"methods": {}
}
In above model, how can I make column1 and column2 as unique key in loopback model? I checked validatesUniquenessOf but it doesn't validate multiple columns.
Thanks
It is working with below:
Table1.validatesUniquenessOf('column1', 'column2');
Not sure, I tried it previously also but that time it was not working. Probably I didn't have re-started loopback server.
The variables in my html content appear to be stripped so no dynamic content is showing up in the email. The template language is set to handlebars in the code and globally.
The documentation does not appear to give any other details or examples. There are no error messages.
var subject = "A really great subject";
var htmlContent = "<h1>Hi, {{user}}</h1><p>{{productName}}?</p><br/><a href='{{unsub redirect_merge_var}}'>Unsubscribe</a>"
var mailJSON ={
"key": "myKey",
"merge_language": "handlebars",
"merge": true,
"global_merge_vars": [
{
"name": "productName",
"content": "Mandrill_User1"
},
{
"name": "user",
"content": "cool guy"
}
],
"message": {
"html": htmlContent,
"subject": subject,
"from_email": "stuff#xxxxxxxxxx.com",
"from_name": "stuff-app",
"to": [
{
"email": ""+person.email,
"name": ""+person.name,
"type": "to"
}
],
"important": false,
"track_opens": null,
"track_clicks": null,
"auto_text": null,
"auto_html": null,
"inline_css": null,
"url_strip_qs": null,
"preserve_recipients": null,
"view_content_link": null,
"tracking_domain": null,
"signing_domain": null,
"return_path_domain": null
},
"async": false,
"ip_pool": "Main Pool"
}
move this:
"merge_language": "handlebars",
"merge": true,
"global_merge_vars": […],
into your message struct. (Official API documentation)
You can also remove your NULL values if you don't need them.
I'm kind of new to this whole posting a question thing, so please be gentle!
I am using Breeze as part of the "Hot Towel" SPA stack and retrieving data from a custom WebApi endpoint written in PHP. It's not a full implementation, I've just written enough to give me what I need.
The metadata my endpoint is generating is as follows:
{
"shortName": "Project",
"namespace": "WebApi.ORM.Cartesius",
"autoGeneratedKeyType": "Identity",
"defaultResourceName": "Project",
"dataProperties": [
{
"name": "id",
"isPartOfKey": true,
"isNullable": false,
"dataType": "Int32"
},
{
"name": "title",
"isNullable": false,
"maxLength": 256,
"dataType": "String"
},
{
"name": "date",
"isNullable": false,
"dataType": "DateTime"
},
{
"name": "review_date",
"isNullable": true,
"dataType": "DateTime"
},
{
"name": "summary",
"isNullable": true,
"dataType": "String"
}
],
"navigationProperties": [
{
"name": "Team",
"entityTypeName": "Team:#WebApi.ORM.Cartesius",
"isScalar": true,
"associationName": "team_project_id_fkey",
"invForeignKeyNames": [
"project_id"
]
},
{
"name": "ProjectAuthor",
"entityTypeName": "ProjectAuthor:#WebApi.ORM.Cartesius",
"isScalar": true,
"associationName": "project_author_project_id_fkey",
"invForeignKeyNames": [
"project_id"
]
},
{
"name": "Itinerary",
"entityTypeName": "Itinerary:#WebApi.ORM.Cartesius",
"isScalar": true,
"associationName": "itinerary_project_id_fkey",
"invForeignKeyNames": [
"project_id"
]
},
Everything is working fine until I try and do an expand on my query:
var query = new breeze.EntityQuery()
.from("Project")
.where("id","eq",project.id)
.expand("ProjectAuthor");
This query returns the following from my endpoint:
[
{
"$id": 1,
"$type": "WebApi.ORM.Cartesius.Project",
"id": 2,
"title": "teat",
"date": "2013-11-04 14:00:00+07",
"review_date": null,
"summary": null,
"ProjectAuthor": [
{
"$id": 2,
"$type": "WebApi.ORM.Cartesius.ProjectAuthor",
"id": 1,
"account_id": 1,
"project_id": 2,
"Project": [
{
"$ref": 1
}
]
},
{
"$id": 3,
"$type": "WebApi.ORM.Cartesius.ProjectAuthor",
"id": 3,
"account_id": 2,
"project_id": 2,
"Project": [
{
"$ref": 1
}
]
}
]
}
]
Then Breeze chokes on it throwing:
TypeError: Object [object Array] has no method 'getProperty'
Debugging points to line 5059 in Breeze where it tries to getProperty on an array of entities rather than a single entity I assumed this had something to do with whether the navigation property was set to scalar or not but switching them around made no difference.
I'm sure I'm doing something massively wrong, but I can't figure out what it is and I've kind of hit a brick wall. I've read the docs from top to bottom and am implementing this as best as I can understand but it's possible I'm a little confused.
Thanks in advance for any help and apologies if I have not made myself clear or provided enough info
I think your problem is in the metadata
"name": "ProjectAuthor",
"entityTypeName": "ProjectAuthor:#WebApi.ORM.Cartesius",
"isScalar": true,
"associationName": "project_author_project_id_fkey",
"invForeignKeyNames": [
"project_id"
]
},
On that nav property Project->ProjectAuthor your telling it that its a scalar but its not in the data set..
"ProjectAuthor": [
{
..........
I've had this problem aswell .. 99% time its a metadata problem, if not there then start cutting metadata apart until you isolate the error .. though I'm sure thats the problem.. you need a hasMany there and an isScalar on the inverse navigation