Skip to content

Commit

Permalink
use uknown json attribute (#189)
Browse files Browse the repository at this point in the history
  • Loading branch information
kbarbounakis authored Jan 16, 2025
1 parent 09cc834 commit 869a550
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 5 deletions.
42 changes: 40 additions & 2 deletions OnJsonAttribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,52 @@ class OnJsonAttribute {
* @returns void
*/
static afterSelect(event, callback) {
const jsonAttributes = event.model.attributes.filter((attr) => {
return attr.type === 'Json' && attr.additionalType != null && attr.model === event.model.name;
const anyJsonAttributes = event.model.attributes.filter((attr) => {
return attr.type === 'Json' && attr.model === event.model.name;
});
if (anyJsonAttributes.length === 0) {
return callback();
}
const jsonAttributes = anyJsonAttributes.filter((attr) => {
return attr.additionalType != null;
}).map((attr) => {
return attr.name
});
// if there are no json attributes with additional type
if (jsonAttributes.length === 0) {
// get json attributes with no additional type
const unknownJsonAttributes = anyJsonAttributes.filter((attr) => {
return attr.additionalType == null;
}).map((attr) => {
return attr.name
});
// parse json for each item
if (unknownJsonAttributes.length > 0) {
const parseUnknownJson = (item) => {
unknownJsonAttributes.forEach((name) => {
if (Object.prototype.hasOwnProperty.call(item, name)) {
const value = item[name];
if (typeof value === 'string') {
item[name] = JSON.parse(value);
}
}
});
};
// iterate over result
const {result} = event;
if (result == null) {
return callback();
}
if (Array.isArray(result)) {
result.forEach((item) => parseUnknownJson(item));
} else {
// or parse json for single item
parseUnknownJson(result)
}
}
return callback();
}

let select = [];
const { viewAdapter: entity } = event.model;
if (event.emitter && event.emitter.query && event.emitter.query.$select) {
Expand Down
12 changes: 10 additions & 2 deletions data-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var DataObjectAssociationListener = dataAssociations.DataObjectAssociationListen
var {DataModelView} = require('./data-model-view');
var {DataFilterResolver} = require('./data-filter-resolver');
var Q = require('q');
var {SequentialEventEmitter} = require('@themost/common');
var {SequentialEventEmitter, Args} = require('@themost/common');
var {LangUtils} = require('@themost/common');
var {TraceUtils} = require('@themost/common');
var {DataError} = require('@themost/common');
Expand All @@ -46,6 +46,7 @@ var { OnJsonAttribute } = require('./OnJsonAttribute');
var { isObjectDeep } = require('./is-object');
var { DataStateValidatorListener } = require('./data-state-validator');
var resolver = require('./data-expand-resolver');
var { isArrayLikeObject } = require('lodash/isArrayLikeObject');
/**
* @this DataModel
* @param {DataField} field
Expand Down Expand Up @@ -1507,7 +1508,14 @@ function cast_(obj, state) {
if (mapping == null) {
var {[name]: value} = obj;
if (x.type === 'Json') {
result[x.name] = isObjectDeep(value) ? JSON.stringify(value) : null;
// check if value is an object or an array
if (value == null) {
result[x.name] = null;
} else {
var isObjectOrArray = isObjectDeep(value) || isArrayLikeObject(value);
Args.check(isObjectOrArray, new DataError('ERR_VALUE','Invalid attribute value. Expected a valid object or an array.', null, self.name, x.name));
result[x.name] = JSON.stringify(value);
}
} else {
result[x.name] = value;
}
Expand Down
21 changes: 21 additions & 0 deletions spec/JsonAttribute.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,27 @@ describe('JsonAttribute', () => {
});
});

it('should update unknown json attribute', async () => {
await TestUtils.executeInTransaction(context, async () => {
const Products = context.model('Product').silent();
let item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)').getItem()
expect(item).toBeTruthy();
item.extraAttributes = {
cpu: 'Intel Core i5',
ram: '8GB'
}
await Products.save(item);
expect(item.dateCreated).toBeTruthy();
item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)')
.select('extraAttributes/cpu as cpu').getItem();
expect(item).toBeTruthy();
expect(item.cpu).toBe('Intel Core i5');
item = await Products.where('name').equal('Apple MacBook Air (13.3-inch, 2013 Version)').getItem();
expect(item).toBeTruthy();
expect(item.extraAttributes).toBeTruthy();
});
});

it('should update json structured value', async () => {
await TestUtils.executeInTransaction(context, async () => {
const Products = context.model('Product').silent();
Expand Down
7 changes: 6 additions & 1 deletion spec/test2/config/models/Product.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"hidden": false,
"sealed": false,
"abstract": false,
"version": "2.2.1",
"version": "2.2.2",
"inherits": "Thing",
"caching": "conditional",
"fields": [
Expand Down Expand Up @@ -232,6 +232,11 @@
"type": "Json",
"indexed": true,
"additionalType": "ProductMetadata"
},
{
"name": "extraAttributes",
"many": false,
"type": "Json"
}
],
"constraints": [
Expand Down

0 comments on commit 869a550

Please sign in to comment.