Please help me write a method for finding child objects. The method receives the name of the object and an array of all possible objects. I need to find an object by the input name in this spike, then see what child objects it has, then go through each object in the same way. Thus, you need to find all the children throughout the cascade. The resulting file is this.ArchiveObject[]. The method I wrote "findChildObjects" goes to infinity and doesn't work correctly.
public async execute(): Promise<void> {
const templateExecutionSteps = await this.getTemplateExecutionSteps();
// Get global describe
const globalDescribe = await SfDescribe.objects(this.auth);
await this.backup.sobjectKeyPrefix(globalDescribe);
// Get names of user-selected objects
const objectsName = [...templateExecutionSteps.keys()].map(objectName => {
const describeObject = globalDescribe.sobjects.find(describeObj => describeObj.name === objectName);
if (!describeObject) throw new Error(`Object ${objectName} not found`);
if (!describeObject.queryable) throw new Error(`Object ${objectName} not queryable`);
return describeObject;
});
// Get names of all objects from org
const globalDescribeNames: string[] = [];
globalDescribe.sobjects.forEach(obj => globalDescribeNames.push(obj.name));
// Get global describe for all objects from org
const describeAllObjects = await SfCompositeUtils.describeObjects(this.auth, globalDescribeNames, true);
// Push global describe for all objects result in map
const globalDescribeMap: Map<string, SFDescribeObjects> = new Map();
describeAllObjects.forEach(objectDescribe => globalDescribeMap.set(objectDescribe.name, objectDescribe));
this.objectsArray = [];
objectsName.forEach(object => {
const allObjects = this.findChildObjects(object.name, globalDescribeMap);
});
}
public findChildObjects(selectedObject: string, globalDescribeMap: Map<string, SFDescribeObjects>): any {
const currentObject: ArchiveObject = {};
console.log(globalDescribeMap);
globalDescribeMap.get(selectedObject).childRelationships.forEach(object => {
if (
this.objectsArray.find(item => item.objectName === object.childSObject && item.referenceField === object.field)
) {
return;
}
currentObject.referenceTo = selectedObject;
currentObject.objectName = object.childSObject;
currentObject.referenceField = object.field;
if (object.cascadeDelete || object.restrictedDelete) {
currentObject.isDelete = true;
this.objectsArray.push(currentObject);
const result = this.findChildObjects(object.childSObject, globalDescribeMap);
this.objectsArray.push(...result);
} else {
currentObject.isDelete = false;
this.objectsArray.push(currentObject);
}
});
return this.objectsArray;
}
export interface ArchiveObject {objectName?: string; referenceField?: string; referenceTo?: string; isDelete?: boolean;}
Here is the globalDescribeMap structure:
'DashboardFeed' => {
actionOverrides: [],
activateable: false,
associateEntityType: 'Feed',
associateParentEntity: 'Dashboard',
childRelationships: [
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object]
],
compactLayoutable: false,
createable: false,
custom: false,
customSetting: false,
deepCloneable: false,
defaultImplementation: null,
deletable: true,
deprecatedAndHidden: false,
extendedBy: null,
extendsInterfaces: null,
feedEnabled: false,
fields: [
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object]
],
hasSubtypes: false,
implementedBy: null,
implementsInterfaces: null,
isInterface: false,
isSubtype: false,
keyPrefix: null,
label: 'Dashboard Feed',
labelPlural: 'Dashboard Feed',
layoutable: false,
listviewable: null,
lookupLayoutable: null,
mergeable: false,
mruEnabled: false,
name: 'DashboardFeed',
namedLayoutInfos: [],
networkScopeFieldName: null,
queryable: true,
recordTypeInfos: [],
replicateable: true,
retrieveable: true,
searchLayoutable: false,
searchable: false,
sobjectDescribeOption: 'FULL',
supportedScopes: [ [Object] ],
triggerable: false,
undeletable: false,
updateable: false,
urls: {
rowTemplate: '/services/data/v50.0/sobjects/DashboardFeed/{ID}',
describe: '/services/data/v50.0/sobjects/DashboardFeed/describe',
sobject: '/services/data/v50.0/sobjects/DashboardFeed'
}
},