Should sub-fields override Intent parameters when launching external app to populate multiple fields?

As an example, imagine a form that has a body::intent on a group like so (from the example in the docs):

org.mycompany.myapp(my_text='Some text', uuid=/myform/meta/instanceID)

This will send an intent to an external app with the extras "my_text" set to "Some text" and "uuid" set to the value of /myform/meta/instanceID. The current values of sub-fields in the group will also be sent in the extras:

The external app is launched with the parameters that are defined in the intent string plus the values of all the sub-fields that are either text, decimal, integer, or binary (filename is sent). Any other sub-field is invisible to the external app.

This means that if I had a field named foo with the value bar, I'd also set an extra "foo" to "bar". However, if I have field named uuid we end up with a clash: the "uuid" extra will now be set to the field "uuid" rather than /myform/meta/instanceID as Collect overrides the parameters set in body::intent if they clash with field names.

There is a risk of accidentally introducing these clashes for any form/external app, but it's especially problematic if the external app's interface lets you specify which return values you want. Imagine an external app that returns "name" and/or "age". It might make sense to design an interface that allows us to pass in true/false for the values we want back (or specify the return names). For instance:

org.mycompany.myapp(name='true', age='false')

The danger here would be that if the group contains a field named "name" (which would be likely), we'd end up overriding "true" with the value of the field.

For my use case, I don't need to pass current field values into the external app, but I imagine that happening by default probably very useful for a lot of folks. It would however make sense to me for this to work the other way around: Collect sets extras for the fields in the group, but parameters specified in body::intent would override them.


Interesting! We should at the very least update the documentation to make this explicit.

My sense is that an override will never be desirable and maybe an error would be more helpful here. That said, I think the issue you describe would be pretty likely to be spotted immediately and easy enough to fix either by changing the form, the app or both.

Interesting! We should at the very least update the documentation to make this explicit.

It's arguably already documented, but I definitely missed it. Definitely not skim safe :laughing:.

Thinking about it further, I guess the way to create an API for an external app that has a configurable return value set is to not use intent parameters at all and instead just include fields for the return values you want. For example, in my earlier "name" and "age" external app you'd just set body::intent to org.mycompany.myapp (with no params) and then include a field named "name" if you want name back. The external app would then be able to determine what to send back just by the presence of the extra. This is less flexible (you have to use specific names for sub-fields), but fits better with the way Collect works.

Just as a side note: my ideal would be that the automatic sending of sub-fields didn't occur at all and you always had to use intent params. I'm guessing that would be hard to take away now though.

1 Like