Listen to Delete and Create of Repeats in a FormEngine

Hello!

In the <PROJECT_NAME> Application we are wrapping the FormEngine with a custom component to automatically save when the user changes the data. We have implemented a listener for the onValueChange Event which will dispatch the ActivityActions.save.started Action (read more).

Lately, we integrated some repeatable data objects to our forms (“Repeats”) and now we are having problems getting notified when the user deletes or adds a new item. I tried to use the onRowEvent but it seems like this feature exists only for custom row events. I technically could intercept the ActivityActions.setData Action, but to differentiate between other situations where this Action will be dispatched is not really trivial and it sounds like a dirty workaround, is there any proper way to listen to this kind of events?

Further, we have to send an explicit Delete Request to our Server and I currently see no way to get the ID of the deleted item inside the Saga which is handling the Save Action, because the item is simply gone. Is there a way to get the difference to the old Data State?

hi @baschir-loud-bluff I think it’s no problems for the new Form Engine?
Hi @stefan-cold-haze I can’t find the event regarding behaviour of Alex above. Could you help?

Hi Alex,

In my opinion, the most generic and robust way is to compare the state. This is what I generally recommend. The downside, however, is that you need code to compare the states.

The second best way is to handle Redux actions in a middleware. The downside here is that it breaks quite easily, when actions are changed or new actions are introduced.

It is also possible to directly hook to React props of a component like you do now, but as you already noticed it can get messy with more complex situations.

PS: I don’t quite understand what you are doing with repeats and deletes on the server side. Sounds a little bit like aggregates / embedded links - something that we are discussing right now for a future version of relationships. Are you (as a team) in contact with Martin Backschat?

So, there is currently no way to get notified when the user adds or removes a row, an event or callback, equivalent to onValueChanged?

You are right, we don’t expose those events. And because the Form Engine wrapper in your version does not use actions, the only option you have is to compare states, which I would recommend anyways.

Please also keep in mind that we consider the activity the smallest transactional unit. Especially in the case of detached repeats, activity.data is only a “working copy”. We use optimistic semantics in the Form Engine, which means we e.g. add detached repeat rows immediately and rollback “on cancel”.

Just to get this right: Following your recommendation, I would compare state changes inside the form engine wrapper, which btw does not know about the data or ui model, because it is a generic wrapper for several usecases. So, I would have to make a deep comparision of the activity’s data prop changes in the component. This would also replace the onValueChanged listener. And if a difference is detected, I would dispatch a custom action that triggers a usecase-specific handler, rather than rely on A12 activity actions like setDirty or save, that could change in the future.

Is this the way you were thinking of @baschir-loud-bluff ?

No, you do it in the “backend” of Redux, i.e. middleware (or in general also reducers but that doesn’t work well with BAP Client at the moment).

Regarding

The problem here is not change of A12 API, but the fact that you cannot rely on a state change being caused by a certain action.

This is by the way not something specific to A12 but a general Redux best practice.

You might want to have a look at the following SO question and the link:

And regarding

This is usually not what you want / not necessary. It’s a little too much to explain here. Have a look at Immutable Data | Redux.

And as always feel free to call me if you would like to discuss it :smiley:

The problem here is not change of A12 API, but the fact that you cannot rely on a state change being caused by a certain action.

Makes sense!

I thought about using store.subscribe or middleware or something, too. The reason, why I wanted to trigger the save action in the wrapper component is because I need to make sure that the forms validation passed, before persisting the data changes, and I can’t find the validation result inside the redux state (which likely has another good reason).

However, this might be a false assumption… I also failed to access the result via the component. I can observe that a change happened by passing an onValidationStateChanged callback, but I can’t determine whether it passed or threw an error. Am I missing something?

By the way, I also noticed that ViewViews.FormEngine is considered deprecated since bap-client@v3.2.0, tried to replace it with FormEngineViews.FormEngineView and failed again, because I can’t find out how it handles custom events (like onEvent in FormEngine).

And as always feel free to call me if you would like to discuss it :smiley:

…Jabber always tells me that you are offline, might be a software issue. I will try to reach you by phone after lunch break :wink: