Select additional fields when getting entity

Anyone know if it’s possible to also select additional data from related entities with the internal button API?

I want to do the same thing as here, but this time around also select to include fields of the returned children, like workflow state.

Else I would have to resort to using the HTTP API.

const field3Collection = {
    "q/select": [{
        "App/Field 3": [
            "q/select": [
                {"workflow/state": ["enum/name"]}
            ],
            "q/limit": 1
        ]
    }],
    "q/limit": "q/no-limit"
};

fibery.getEntityById("App/Name", entity["My entity"], ["Field 1", "Field 2", field3Collection]);

For now I’ll use HTTP request and API.

I was looking at the original post you referred to and was playing around with something similar. I thought I would upload some sample code that shows how to get properties (incl collections) of related types using the action button.
In this case, I have a Project with multiple related Tasks. When the button is pressed (for any Task) the code finds the parent Project and then finds all Tasks associated with this Project and iterates through renaming them.
If I’ve understood your problem, it would seem to be possible to adapt the code to get other properties of the parent entity as you need.

const api = context.getService("fibery");

for (const e of args.currentEntities) {

    const task = await api.getEntityById(e.type, e.id, ["Project"])
    const projectID = task["Project"].id

    const project = await api.getEntityById("Project", projectID, ["Name","Tasks"])
    const projName = project["Name"]

    const taskCollection = project["Tasks"].map(u => u.id)

    var i = 0
    for (const task of taskCollection) {
        i = i + 1
        const taskObj = await api.getEntityById("Task", task, ["Property"])
        const newName = projName + " " + i + " - " + taskObj["Property"]
        await api.updateEntity("Task", task, { "Name": newName })
    }
}

FYI, I’m not a coder, so I’m sure it could be done more nicely :-/

Using getEntityById unfortunately only gets the ID of collections (like workflow state). In that case I would then have to at least get each uniquely appearing state ID to read its data that I can use for further logic.

Not sure how fast that would be compared to a single request that is able to get all data. Depending on how the backend logic works and other conditions, either could be faster and more efficient than the other :man_shrugging:

By the way for the case above (load nested entities with fields), we introduced getEntitiesByIds method. So you first load entities of level 1, and then load entities of level 2 with required fields, performing only 1 query. So this still be good in terms of efficiency.
But definitely commands api will be still faster, as only one query is required. But as commands api is a bit cubersome, we introduced this simplified shortcuts methods in button api.

@Chr1sG Using what Sergey suggested using method to get multiple entities all at once (I think he meant at least):

const tasks = await api.getEntityById("Project", projectID, ["Name","Tasks"]);

Returns something like

[{
	name:"Task 1",
	state: {
		Id: "aaaaaa-bbbbbbbb"
	}
},{
	name:"Task 2",
	state: {
		Id: "bbbbbb-aaaaaaaaa"
	}
}]

which is not enough info for state, so I would have group them uniquely:

const stateIds = new Set(tasks.map(t => t.state.Id));

then require all those tasks with a second query

const states = fibery.getEntitiesByIds("Task", Array.from(stateIds), ["enum/name"]);

to then proceed with logic. This works too of course. As Sergey said, it is simpler to create, less of a mess, but a single query is faster.

2 Likes