Name | Description |
---|---|
Complex Hive type | Any non-primitive type or in simple words: Data which contains key-value pairs Examples:
|
Raw data | Unconverted data which is sent between client & server
|
Parsed data | Raw data which got parsed/converted to a JS object
|
Working with complex Hive types was quite cumbersome in previous versions and had a mixed behavior:
CmpUtils.getRecord...()
)CmpUtils.setCmpInput()
) it had to be parsed to raw dataTo sum it up, it was the job of the developer to know when and how to convert data.
From now on, conversion of raw data isn't necessary anymore!
The functions of CmpUtils
always return parsed data when the component is of a complex Hive type
and it can also be used to set any cmp-input with it, as long as the type matches.
Besides the record components it's now required to register the TS interface of all components which are used
in CustomJS
and consist of a complex Hive type.
Recommended process to do so: Hive Interface Registration - Mapping
To find unregistered components easier an automatic check happens, which compares the components defined
in CustomJSCmps
with the registered ones. So after updating the cjs-utils
version simply run the cfgr in preview-mode and check for new errors.
Go through them from top to bottom as some errors might appear only due to leading ones. After you registered
the missing interfaces, all such errors should be gone and you can proceed with the next chapter.
Every project has its own kind of conversion, so the following chapter should only be seen as a collection of guidelines and hints.
For example, if there's an Element
and ElementList
only rework the Element
until all build-errors are resolved.
Only then proceed with the ElementList
.
toCmpValue
, fromCmpValue
, toCmpInput
, fromCmpInput
, syncFrom
, syncTo
, ...const ElementRecIndices = { Key: 0, Name: 1 };
...Column
or ...Cols
If the conversion logic is contained in its own class, which only consists of those conversion
functions (toCmpInput
, fromCmpInput
, ...) and without additional business logic
(e.g. getPrice()
, calcBoundingBox()
) the whole class can probably be deleted.
Afterwards replace any occurences where the class gets instantiated, a conversion function is called or its type
is used.
Remove all the conversion functions (check the body beforehand for any special logic) and go through your errors.
Options to proceed:
Keep class
If you want to keep your class, no further steps should be required.
Change to module with exported functions
Get rid of the class and change every function to an exported function which takes its "instance" as first parameter.
Be careful to replace any usage of this
.
// Before
export class ElementItem {
getPrice(withVAT) {
return withVAT ? this.price * 1.2 : this.price;
}
}
// After
export function getPrice(elementItem, withVAT) {
return withVAT ? elementItem.price * 1.2 : elementItem.price;
}
any
or @ts-ignore
which are used in combination with a CmpUtils
function.CmpUtils
with no typing at allconst data = CmpUtils.getCmpValue('MyData');
const data = /** @type {MyComplexData} */ (CmpUtils.getCmpValue('MyData'));
If the interfaces are correctly registered, there shouldn't be any cases where a typing isn't possible. Otherwise reach out to your development team.
E.g. myObj[123]
or myObj[asdf]
instead of myObj.asdf
Errors related to this might be hard to spot and therefore requires to test the final configurator very well. You might search for following occurences:
// Retrieving data by number index
// Error:
const newValue = myRecord[0];
// Fixed:
const newValue = myRecord.Key;
// Object which defines indices
// Error:
const MyRecordCols = { Key: 0, Name: 1 };
const newValue = myRecord[MyRecordCols.Key];
// Fixed:
const newValue = myRecord.Key;
CmpUtils.getRecordCmpColValue
This function required to additionaly hard-code the ColName
although it's already defined in the interface.
Instead retrieve the whole record and access its property.
Before
export class ColNames {
static get InitMsg() {
return 'InitMsg';
}
static get LoadModelMsg() {
return 'LoadModelMsg';
}
}
const loadModelMsg = CmpUtils.getRecordCmpColValue(CmpNames.StatusMsgs, ColNames.LoadModelMsg);
displayMessage(loadModelMsg);
After
interface StatusMsgs {
InitMsg: string;
LoadModelMsg: string;
}
const statusMsgs = /** @type {StatusMsgs} */ CmpUtils.getRecordCmpValue(CmpNames.StatusMsgs);
displayMessage(statusMsgs.LoadModelMsg);
CmpUtils.getCmp
There is no direct replacement for this function.
For every usage there should exist a better suited CmpUtils
function by now.
Otherwise reach out to your development team.
CmpUtils.onAnyCmpValueChanged
In previous versions the returned callback param changedCmps
sometimes contained "more than requested" as new values of all cmps which have changed where included instead of only the ones which were actually requested with the cmpNames
param of CmpUtils.onAnyCmpValueChanged.
The returned changedCmps
now only contains values which are explicitly defined in the cmpNames
param (and actually changed).
CmpUtils.onAnyCmpValueChanged(
changedCmps => {
// ==============
// Before v6.1.0:
// ==============
//
// If cmps `Chairs` & `Cabinets` changed, `changedCmps` also included the new value of
// `Chairs` even though it was not requested with the `cmpNames` param.
//
// ==============
// After v6.1.0:
// ==============
//
// The new value of `Chairs` (or any other cmp which was not requested with the `cmpNames`
// param) is not included in the given `changedCmps` anymore.
//
// E.g.:
// - Cmps `Cabinets` & `Chairs` change -> `changedCmps` only contains the new value of
// `Cabinets`
// - Cmps `Cabinets`, `Chairs` & `Desks` change -> `changedCmps` contains the new values
// of `Cabinets` & `Desks`
},
['Cabinets', 'Desks'] // <- Requested `cmpNames`
);
Generated using TypeDoc