How to detect changes in computed field values?

I’m trying to trigger some logic in a Saga based on the change of a computed field value.

For regular fields, a form-engine/event/VALUE_CHANGE event is dispatched when they change. However, this event is not triggered for computed fields.

Is there a straightforward way to hook into the computation process so I can detect when a computed field’s value changes inside a saga?

Hi,
We provide some functionality for detecting state transitions, that can be used in a custom saga. In can be found in the core/store/StoreSagas namespace.
Typedoc: GetA12 Login
For example, the StoreSagas.waitForStateChange saga can be used and called with a selector, that returns true, when the desired computed field instance has changed in the document.
It halts the execution of your custom saga until, the state change happened.

For a very simple implementation of such a selector, you need the EntityInstancePath of the field instance in the document for which you expect a change and the initial value of that instance.
Then you could use the kernel’s DocumentService.getAssignedObject function to find the current value in the document for each state change.
The selector would only return true, when the current value differs from the known initial value.

Example code (not tested!):

const fieldPath: EntityInstancePath = [
    { elementName: "root", index: 1 },
    { elementName: "computedField", index: 1 }
];
const initialValue = "foo";

const hasStateChanged = yield* call(() =>
    StoreSagas.waitForStateChange(
        computedFieldValueHasChanged(activityId, fieldPath, initialValue)
    )
);

function computedFieldValueHasChanged(
	activityId: string,
	computedFieldPath: EntityInstancePath,
	initialValue: unknown
): Selector<{ returnValue: FieldInstanceValue | undefined; stateChanged: boolean }> {
	const documentService = new DocumentServiceFactory().getDocumentService();
	return (state): { returnValue: boolean; stateChanged: boolean } => {
		const { document } = FormEngineSelectors.dataState(activityId)(state);
		const currentValue = documentService.getAssignedObject(
			document as GroupInstance,
			computedFieldPath
		);
		if (currentValue !== initialValue) {
			return { returnValue: currentValue, stateChanged: true };
		}

		return { returnValue: currentValue, stateChanged: false };
	};
}

Hope this helps.

Greetings
Conrad

Hello @maximilian-pure-flame , I am a member of the Discourse team. I can see that there was a new response to your question on the Topic of the discussion. Do you find it helpful, or should the question remain open?

Thanks ahead for your feedback and have a nice rest of the day!

Thanks for the response. This helped to solve my issue. I missed this part in the documentation.