Dynamically build display for JSON-Data and JSONschema - javascript

I have a JSON Schema which describes the data I want to display.
{
"title": "BeautifulDataRequest",
"type": "object",
"properties": {
"DateOfRequest": {
"type": "string"
},
"PeopleRequested": {
"type": "string"
},
"JourneyType": {
"type": "string"
},
"AccommodationDate": {
"type": "string"
},
"Request": {
"type": "string"
}
}
}
And I have JSON-Data I want to display. The JSON can contain additional fields which are not described in the JSON schema, but I only want to display the values described in this schema.
The schema and the data can vary depending on the data type.
Since there are a lot of different schemata I am looking for something that can "create a display dynamically depending on the schema".
I already worked with JSONEditor, but this editor is for changing the schema, more than displaying the data. I can simply display the data by setting all fields to read only, but I think that is kind of awkward.
Sample data:
{
"Id": "9be37e98-bc35-4aa5-8c74-39ea76415db5",
"UserId": "c7c76272-e6f3-e811-93fc-005056b22eda",
"TempId": null,
"UserTypeName": null,
"StoreCode": "fdsdf",
"CurrentStepCode": "Done",
"StoreAssignedName": "",
"CreateDate": "2018-11-30T10:05:25.867",
"isDeleted": false,
"AdditionalData": {},
"Type": {
"Id": "c7c76272-e6f3-e811-93fc-005056b22eda",
"Name": "Request"
},
"DateOfRequest": "17.11.2018",
"PeopleRequested": "2",
"JourneyType": "Doppelzimmer",
"Request": "Nachfrage zur Reise",
"AccommodationDate": "Insel Rügen – Perle der Ostsee"
}
To put it in a nutshell:
I have JSON-data which is described by a JSON-schema.
I want to display this data based on the JSON-schema.
The front end is HTML with bootstrap2 and JavaScript available.
Question:
Does anybody know a way/(JavaScript)library to dynamically display JSON-Data described by JSON-Schema?

var schema = {
"title": "BeautifulDataRequest",
"type": "object",
"properties": {
"DateOfRequest": {
"type": "string"
},
"PeopleRequested": {
"type": "string"
},
"JourneyType": {
"type": "string"
},
"AccommodationDate": {
"type": "string"
},
"Request": {
"type": "string"
}
}
};
var sampleData = [{
"Id": "9be37e98-bc35-4aa5-8c74-39ea76415db5",
"UserId": "c7c76272-e6f3-e811-93fc-005056b22eda",
"TempId": null,
"UserTypeName": null,
"StoreCode": "fdsdf",
"CurrentStepCode": "Done",
"StoreAssignedName": "",
"CreateDate": "2018-11-30T10:05:25.867",
"isDeleted": false,
"AdditionalData": {},
"Type": {
"Id": "c7c76272-e6f3-e811-93fc-005056b22eda",
"Name": "Request"
},
"DateOfRequest": "17.11.2018",
"PeopleRequested": "2",
"JourneyType": "Doppelzimmer",
"Request": "Nachfrage zur Reise",
"AccommodationDate": "Insel Rügen – Perle der Ostsee"
}, {
"Id": "1",
"UserId": "2",
"TempId": null,
"UserTypeName": null,
"StoreCode": "fdsdf",
"CurrentStepCode": "Done",
"StoreAssignedName": "",
"CreateDate": "2018-11-30T10:05:25.867",
"isDeleted": false,
"AdditionalData": {},
"Type": {
"Id": "c7c76272-e6f3-e811-93fc-005056b22eda",
"Name": "Request"
},
"DateOfRequest": "test",
"PeopleRequested": "test",
"JourneyType": "test",
"Request": "test",
"AccommodationDate": "test"
}];
function matchSchema (samples, schema) {
var dataset = [];
samples.forEach( sample => {
// Deep clone schema (may use lodash or underscore)
var clone = jQuery.extend(true, {}, schema);
_.findKey(schema.properties, (value, key) => {
if (_.has(sample, key)) {
// You may validate type here
clone.properties[key] = sample[key];
}
});
// Add clone to dataset
dataset.push(clone);
});
return dataset;
}
var result = matchSchema(sampleData, schema);
var $table = $('#result-table tbody');
console.log(result);
// Draw table
result.forEach(item => {
var row = $('<tr/>');
_.each(item.properties, (value, key) => {
var column = $('<td/>').text(value);
row.append(column);
});
$table.append(row);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://fastcdn.org/Underscore.js/1.8.3/underscore-min.js"></script>
<table id="result-table" border="1">
<thead>
<tr>
<th>col1</th>
<th>col2</th>
<th>col3</th>
<th>col4</th>
<th>col5</th>
</tr>
</thead>
<tbody>
</tbody>
</table>

Related

How to print huge number of items from the json array

This is my json format with that im displaying my array items like this.
If i have more items in my array mean how can i print that all using for loop or is there any method available to print all that items in an array?
{
"workers": [
{ "id": "5001", "type": "Basic" },
{ "id": "5002", "type": "Admin" },
{ "id": "5003", "type": "Basic" }
],
"clients": [
{ "id": "5004", "type": "Pro" },
{ "id": "5005", "type": "Basic" },
{ "id": "5006", "type": "Basic" },
{ "id": "5007", "type": "Pro" }
]
}
<script>
const api_url = "API URL";
async function get_data_from_api() {
const response = await fetch(api_url);
var data = await response.json();
var track = data["workers"][2]["id"];
document.getElementById('demo2').innerHTML = track ;
}
</script>
Reference:
JSON.stringify()
const o = {
"workers": [
{ "id": "5001", "type": "Basic" },
{ "id": "5002", "type": "Admin" },
{ "id": "5003", "type": "Basic" }
],
"clients": [
{ "id": "5004", "type": "Pro" },
{ "id": "5005", "type": "Basic" },
{ "id": "5006", "type": "Basic" },
{ "id": "5007", "type": "Pro" }
]
};
output.innerHTML = JSON.stringify(o, undefined, 2);
<pre id="output"></pre>

How to dynamically create and iterate Json Object inside a Json Array using Postman - Javascript

I have a payload like mentioned below :
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters": {
"batter": [
{
"id": "1001",
"type": "Regular"
},
{
"id": "1002",
"type": "Chocolate"
},
{
"id": "1003",
"type": "Blueberry"
},
{
"id": "1004",
"type": "Devil’sFood"
}
]
},
"topping": [
{
"id": "5001",
"type": "None"
},
{
"id": "5002",
"type": "Glazed"
},
{
"id": "5005",
"type": "Sugar"
},
{
"id": "5007",
"type": "PowderedSugar"
},
{
"id": "5006",
"type": "ChocolatewithSprinkles"
},
{
"id": "5003",
"type": "Chocolate"
},
{
"id": "5004",
"type": "Maple"
}
]
}
**I want to increment the json objects dynamically(it can be a duplicate as well) which is inside the array topping based on the array size. For example if mention the array size as topping[10] it is suppose to create a payload of 10 objects and push those 10 objects of similar type inside the array topping ** Is it possible to dynamically create json objects and post the request in postman??
Kind note : The size of the array should be parameterized. Please let me know.
Please find the image highlighted in green. I want to dynamically increase the payload(topping array size based on the index using postman
You could do this:
Tab Pre-request
let req = {
"id": "0001",
"type": "donut",
"topping": []
};
let numberOfTopping = 5;
for (let i = 0; i < numberOfTopping; i++) {
let toppingItem = {
"id": `${_.random(5001, 5010)}`,
"type": `${_.sample(["Glazed", "Sugar", "None"])}`
};
req.topping[i] = toppingItem;
}
pm.variables.set("req", JSON.stringify(req));
Tab body
Result
{
"id": "0001",
"type": "donut",
"topping": [
{
"id": "5006",
"type": "Glazed"
},
{
"id": "5001",
"type": "Sugar"
},
{
"id": "5006",
"type": "Glazed"
},
{
"id": "5006",
"type": "None"
},
{
"id": "5008",
"type": "Sugar"
}
]
}

Loopback query with where inside include

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
}
}
}
}

Deriving the list of JSON Paths from a JSON Schema model

I am looking for a Javascript library to list the possible Json Paths based on a Json Schema.
For a json schema like below, I want to list the possible json paths.
{
"$id": "https://example.com/person.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Customer",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
},
"address": {
"type": "object",
"city": {
"type": "string",
},
"country": {
"type": "string",
}
}
}
}
Possible Json Paths: firstName, lastName, age, address.city, and address.country
Based on #customcommander's answer
Add support for $ref (prevent recursion)
Add hierarchy parents paths too (i.e. a.b.c -> a + a.b + a.b.c)
Add support for array items (using [] as a generic indexer)
const _derivePathsFromSchema = (schema, properties, defined) => {
let paths = [];
if (!properties) return paths;
return Object.keys(properties).reduce((paths, childKey) => {
let child = properties[childKey];
const { $ref, ...childProperties } = child;
if ($ref?.startsWith('#/definitions/')) {
const definition = $ref.substr($ref.lastIndexOf('/') + 1);
if (!defined.includes(definition)) // prevent recursion of definitions
{
defined.push(definition);
child = {
...schema.definitions[definition], // load $ref properties
...childProperties, // child properties override those of the $ref
};
}
}
if (child.type === 'object') {
return paths.concat(childKey, _derivePathsFromSchema(schema, child.properties, defined.slice()).map(p => `${childKey}.${p}`));
}
if (child.type === 'array' && child.items?.properties) {
return paths.concat(childKey, `${childKey}[]`, _derivePathsFromSchema(schema, child.items.properties, defined.slice()).map(p => `${childKey}[].${p}`));
}
return paths.concat(childKey);
}, paths);
};
const derivePathsFromSchema = schema => _derivePathsFromSchema(schema, schema.properties, []);
console.log(derivePathsFromSchema({
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"BType": {
"type": "object",
"properties": {
"a": {
"$ref": "#/definitions/AType"
}
}
},
"AType": {
"type": "object",
"properties": {
"b": {
"$ref": "#/definitions/BType"
}
}
}
},
"type": "object",
"properties": {
"a": {
"$ref": "#/definitions/AType"
},
"b": {
"$ref": "#/definitions/BType"
},
"id": {
"type": "string"
},
"array": {
"type": "array",
"items": {
"type": "object",
"properties": {
"item": { "type": "string" }
}
}
},
"obj": {
"type": "object",
"properties": {
"nested": { "type": "string" }
}
}
}
}));
You don't necessarily need a library for that. You can use a simple recursive function:
var schema = {
"$id": "https://example.com/person.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Customer",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
},
"address": {
"type": "object",
"properties": {
"city": {
"type": "string",
},
"country": {
"type": "string",
}
}
}
}
};
var path = ({properties}) =>
Object.keys(properties).reduce((acc, key) =>
acc.concat(properties[key].type !== 'object' ? key :
path(properties[key]).map(p => `${key}.${p}`)), []);
console.log(
path(schema)
);

json-schema-faker including extra url in results

I'm setting up json-schema-faker to create some mock data for a project.
When I generate the data it includes an extra bit with the following as the last item in the generated data.
"id": "http://json-schema.org/schema#"
Here is my schema (from a file named 'mockDataSchema.js'):
exports.schema = {
"type": "object",
"properties": {
"users": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"type": "object",
"properties": {
"id": {
"type": "number",
"unique": true,
"minimum": 1
},
"firstName": {
"type": "string",
"faker": "name.firstName"
},
"lastName": {
"type": "string",
"faker": "name.lastName"
},
"email": {
"type": "string",
"faker": "internet.email"
}
},
"required": ["id", "firstName", "lastName", "email"]
}
}
},
"required": ["users"]
}
The code to generate the data ('generate-mock-data.js'):
var jsf = require('json-schema-faker')
var schema = require('./mockDataSchema')
var fs = require('fs')
var chalk = require('chalk')
const json = JSON.stringify(jsf(schema))
console.log(json)
fs.writeFile('./src/api/db.json', json, function(err) {
if (err) {
return console.log(chalk.red(err))
} else {
console.log(chalk.green('Mock data generated.'))
}
})
Add the data that is returned:
{
"schema": {
"users": [
{ "id": 25582343, "firstName": "Brycen", "lastName": "Dickens", "email": "Angelica_Jakubowski#hotmail.com" },
{ "id": 39817508, "firstName": "Marisa", "lastName": "Terry", "email": "Arlo.Hermann0#yahoo.com" }
]
},
"id": "http://json-schema.org/schema#"
}
I've been unable to determine why it includes the "id": "http://json-schema.org/schema#"
I would like to get rid of that line. I'll be using this with 'json-server' to provide a mock api and it chokes on that line.
Figured this out.
exports.schema = {
was causing jscon-schema-faker to interpret '.schema' as part of the schema.
Changed to
module.exports = {
and the trailing schema link wnet away.

Categories

Resources