| 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 ...ColsIf 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.getRecordCmpColValueThis 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.getCmpThere 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.onAnyCmpValueChangedIn 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