I need to execute two delete record smart service from one saveinto. Evidently, this is not possible as it throws an error.
" An error occurred while executing a save: Expression evaluation error : Attempted to run a second smart service, but only one smart service can be run per expression evaluation."
Here is the business issue.
I have an interface where Parish managers can specify if they have a preference as to the type and the languages spoken my missionaries that speak at their church. This is one in the Parish Profile screen and the profile is saved year after year. The current parish manager can change the preferences that were set last year. There are two record types that hold this information, Parish Profile Language Type and Parish Profile Speaker Type. The local variables in the interface that holds this data are local!speakerPreference and local!languagePreference. They both are types as their respective record types and can hold more than one record.
The radioButtonField sets if they have a preference either true or false. Here is the code for that.
a!radioButtonField( choiceLabels: { "Yes", "No" }, choiceValues: { true, false }, label: "Is there a Speaker Preference", labelPosition: "ABOVE", value: local!selectedParishProfile.speakerPreference, saveInto: { a!save( local!selectedParishProfile.speakerPreference, save!value ), if(count(local!speakerPreference)>0, a!deleteRecords( records: local!speakerPreference, onSuccess: a!save( local!speakerPreference, remove( local!speakerPreference, count(local!speakerPreference) ) ) ), {} ), if(count(local!languagePreference)>0, a!deleteRecords( records: local!languagePreference, onSuccess: a!save( local!languagePreference, remove( local!languagePreference, count(local!languagePreference) ) ) ), {} ) }, showWhen: if( a!isNotNullOrEmpty( local!selectedParishProfile.speakerRequired ), local!selectedParishProfile.speakerRequired, false ), required: if( a!isNotNullOrEmpty( local!selectedParishProfile.speakerRequired ), local!selectedParishProfile.speakerRequired, false ), choiceLayout: "COMPACT", choiceStyle: "STANDARD", spacing: "EVEN_MORE" ),
It seems from reading other posts, that I have to create a process model or record action to take care of this and pass in the two local variables to delete the records.
Is this true?
Discussion posts and replies are publicly visible
This is correct. Create a process model.
There is an upcoming Appian Rocks (https://appian.rocks) podcast episode where we discuss the reasons for this design decision.
One potential workaround is to contrive a way for the setting to require 2 user clicks (say, a confirmation button, or post confirmation, etc). That might or might not be feasible given the other on-form designs of course.
Frankly I, too, sometimes find this limitation a bit trivial (they want to prevent us from execting dozens or hundreds of smart services in one SaveInto, and, for some reason, the only way they can think of to do that is to limit it to 1? what?) - but honestly it's not THAT much of a lift to simply whip up a process model that takes care of all of it, and simply swap out a startProcess call.
Thanks again Stefan!!!
I agree! I think Appian puts in a lot of limitations because they are afraid that we creative programmers will find ways to do......
What? I love their single user licensing model, how would allowing us to put in two or more smart services impact their bottom line?
I shouldn't have been so quick. I created the PM, it has two process variables; languagePreference and speakerPreference. I'm having issues with receiving the error codes from the process model.
Here is the code that calls the process
a!radioButtonField( choiceLabels: { "Yes", "No" }, choiceValues: { true, false }, label: "Is there a Speaker Preference", labelPosition: "ABOVE", value: local!selectedParishProfile.speakerPreference, saveInto: { a!save( local!selectedParishProfile.speakerPreference, save!value ), a!startProcess( processModel: cons!PMSO_deleteSpeakerandLanguagePreferences, processParameters: a!map( languagePreference: local!languagePreference, speakerPreference: local!speakerPreference ), onSuccess: { a!save(local!languagePreferencesDeletedSuccess, fv!processInfo.pv.LanguageErrorOccured), a!save(local!speakerPreferencesDeletedSuccess, fv!processInfo.pv.SpeakerErrorOccured) } ), }, showWhen: if( a!isNotNullOrEmpty( local!selectedParishProfile.speakerRequired ), local!selectedParishProfile.speakerRequired, false ), required: if( a!isNotNullOrEmpty( local!selectedParishProfile.speakerRequired ), local!selectedParishProfile.speakerRequired, false ), choiceLayout: "COMPACT", choiceStyle: "STANDARD", spacing: "EVEN_MORE" ),
The process variables LanguageErrorOccured and SpeakerErrorOccured, are being populated in the PM.
But not the local variable
This is the reason: https://docs.appian.com/suite/help/25.1/functions-side-effects.html
If you're using the newer a!startProcess(), make sure you set "is synchronous" to TRUE - the newer version doesn't obey (or care about) activity chaining in the process model, and our only options are now to either assume the process has completed or wait for a time-out (though small, utility-based process models should pose little or no issue for this constraint).