I'm currently developing a pluggable widget that retrieves data from a microflow (List of Object, with one Object at index 0 (List<Object>[0] = Object
), seems to be a limitation with Mendix).
I can retrieve the objects content just fine but as soon as there are nested objects within the object, I cannot retrieve their data. The first object is retrieved by its Symbol in TS.
const mxObject = (item as any)[mxObjectSymbol];
const [extractedData, mainDebug] = extractFromMxObject(mxObject, debug);
// Extract data from MxObject
function extractFromMxObject(mxObject: any, debug: string = "", parentPath: string = ""): [Record<string, any>, string] {
const extractedData: Record<string, any> = {};
try {
if (typeof mxObject.getAttributes === 'function') {
const attrList = mxObject.getAttributes();
debug += `${parentPath ? `[${parentPath}]` : ''} Attributes: ${attrList.join(', ')}\n`;
for (const attr of attrList) {
try {
// Get attribute value
const value = mxObject.get(attr);
const fullPath = parentPath ? `${parentPath}.${attr}` : attr;
debug += `Retrieved attribute ${fullPath}, type: ${typeof value}\n`;
// Store value
extractedData[attr] = value;
debug += `Extracted ${fullPath}: ${value}\n`;
// Handle potential reference attributes (ending with _id)
if ((attr.endsWith('_id') || attr.endsWith('ID')) && typeof value === 'string') {
// Try to get the referenced object
const baseAttr = attr.replace(/_id$/i, '').replace(/_ID$/i, '');
try {
if (typeof mxObject.get === 'function') {
const refObj = mxObject.get(baseAttr);
if (refObj && typeof refObj === 'object') {
debug += `Found referenced object for ${fullPath} via ${baseAttr}\n`;
// Extract data from referenced object
const [refData, refDebug] = extractFromMxObject(refObj, "", fullPath);
debug += refDebug;
// Store the extracted data with the base attribute name
extractedData[baseAttr] = refData;
}
}
} catch (refErr) {
debug += `Error retrieving reference for ${fullPath}: ${refErr}\n`;
}
}
// If this is a nested MxObject, apply extraction recursively
if (typeof value === 'object' && value !== null) {
// Try to detect if it's a Mendix object
const hasGetMethod = typeof value.get === 'function';
const hasGetAttributes = typeof value.getAttributes === 'function';
if (hasGetAttributes || hasGetMethod) {
debug += `Found nested MxObject in attribute ${fullPath}\n`;
// Apply the same extraction logic to the nested object
const [nestedData, nestedDebug] = extractFromMxObject(value, "", fullPath);
// Replace the original value with the extracted data
extractedData[attr] = nestedData;
debug += nestedDebug;
}
}
} catch (e) {
debug += `Error extracting ${parentPath ? `${parentPath}.${attr}` : attr}: ${e}\n`;
}
}
} else {
debug += `${parentPath ? `[${parentPath}]` : ''} getAttributes method not found on object\n`;
// Fallback: try to access properties directly
if (mxObject && typeof mxObject === 'object') {
for (const key in mxObject) {
try {
if (typeof mxObject[key] !== 'function') {
const value = mxObject[key];
const fullPath = parentPath ? `${parentPath}.${key}` : key;
extractedData[key] = value;
debug += `Direct property extraction ${fullPath}: ${value}\n`;
}
} catch (e) {
// Ignore errors on direct property access
}
}
}
}
} catch (e) {
debug += `Error in extraction${parentPath ? ` for ${parentPath}` : ''}: ${e}\n`;
}
return [extractedData, debug];
}
I thought that I could use the same function recursively to check for other objects (Attributes that look like "MyModule.SomeEntity_Element1_x" as far as I know). However, it doesnt seem to work and only returns the String ID of that object.
Has anyone had experience with that?