I have created an application that uses a public API as an Integration to retrieve the required data from a 3rd party website and store it in the Appian database.
So my application is a "Dictionary Book" and I have created a CDT for the same using these fields:
id word phonetic origin definition example searchedBy searchedAt
Next, I created an interface wherein I have passed this CDT, readOnly and cancel as a rule input. The user needs to fill and submit the "word" field, and the "searchedBy" and "searchedAt" fields are set using loggedInUser and now function. The rest of the fields would get their respective data via Integrations.
I created the entire process in the Process Model and I was able to get and save the data for all the CDT fields without any errors.
But when I added this interface as a page to my site, and tried to execute this interface, it gave me an error saying:
Expression evaluation error [evaluation ID = 831a9:498d4] in rule 'lcp_searchwordv1' : An error occurred while executing a save: Expression evaluation error: The save target must be a local variable that does not refresh on every evaluation or on an interval, a process variable, or a node input (or a rule input passed one of those three), but instead was: [id=, word=, phonetic=, origin=, definition=, example=, searchedBy=, searchedAt=]
I have attached the code for the interface as well. Please help me to resolve this issue
a!localVariables( local!username: loggedInUser(), local!time: now(), local!main: ri!dictionaryV1.word, a!formLayout( label: "", contents: { a!richTextDisplayField( labelPosition: "COLLAPSED", value: { a!richTextItem( text: { a!richTextIcon( icon: "book" ), " Free Dictionary Search" }, color: "#4cb020", size: "LARGE", style: { "STRONG" } ) }, marginBelow: "MORE" ), a!columnsLayout( columns: { a!columnLayout( contents: { a!textField( label: "Search a Word", labelPosition: if( ri!readOnly, "ADJACENT", "ABOVE" ), instructions: "", helpTooltip: "Make sure the Entered Word is Valid", placeholder: "--- Enter the word to be searched in the Dictionary ---", value: local!main, saveInto: local!main, characterLimit: 255, showCharacterCount: false, required: true, readOnly: ri!readOnly ), a!pickerFieldUsers( label: "User Name", labelPosition: "ABOVE", instructions: "If your name is not displayed / unavailable, please contact your Branch Supervisor", maxSelections: 1, value: local!username, saveInto: local!username, showWhen: or( isnull(ri!readOnly), ri!readOnly=false()), required: true, disabled: false, validations: {} ), a!textField( label: "Origin", labelPosition: if( ri!readOnly, "ADJACENT", "ABOVE" ), value: {}, saveInto: {}, characterLimit: 255, showCharacterCount: false, showWhen: ri!readOnly = true(), readOnly: ri!readOnly ), a!textField( label: "Example", labelPosition: if( ri!readOnly, "ADJACENT", "ABOVE" ), value: {}, saveInto: {}, characterLimit: 255, showCharacterCount: false, showWhen: ri!readOnly = true(), readOnly: ri!readOnly ) } ), a!columnLayout( contents: { a!textField( label: "Language Selected", labelPosition: "ABOVE", instructions: "The system selects ""English"" as the Default Language for all searches", value: "English", saveInto: {}, refreshAfter: "UNFOCUS", required: true, disabled: true, validations: {} ), a!dateTimeField( label: "Date & Time", labelPosition: if( ri!readOnly, "ADJACENT", "ABOVE" ), value: local!time, saveInto: local!time, required: true, readOnly: ri!readOnly, disabled: false ), a!textField( label: "Phonetic", labelPosition: if( ri!readOnly, "ADJACENT", "ABOVE" ), value: {}, saveInto: {}, characterLimit: 255, showCharacterCount: false, showWhen: ri!readOnly = true(), readOnly: ri!readOnly ), a!textField( label: "Definition", labelPosition: if( ri!readOnly, "ADJACENT", "ABOVE" ), value: {}, saveInto: {}, characterLimit: 255, showCharacterCount: false, showWhen: ri!readOnly = true(), readOnly: ri!readOnly ), a!textField( label: "Searched By", labelPosition: if( ri!readOnly, "ADJACENT", "ABOVE" ), value: ri!dictionaryV1.searchedBy, saveInto: ri!dictionaryV1.searchedBy, characterLimit: 255, showCharacterCount: false, showWhen: ri!readOnly = true(), readOnly: ri!readOnly ) } ) } ) }, buttons: a!buttonLayout( primaryButtons: { a!buttonWidget( label: "Search", saveInto: { a!save(target: ri!dictionaryV1.searchedBy, value: local!username), a!save(target: ri!dictionaryV1.searchedAt, value: local!time), }, submit: true, style: "PRIMARY" ) }, secondaryButtons: { a!buttonWidget( label: "Cancel", value: true, saveInto: ri!cancel, submit: true, style: "NORMAL", validate: false ) }, showWhen: or( isnull( ri!readOnly ), not( ri!readOnly ) ) ) ) )
Discussion posts and replies are publicly visible
Hi, by default, variables defined under a!localVariables() will attempt to refresh each time any referenced variables are changed, so your definition of local!main will throw this error when you attempt to save into it (it can be only one or the other, a refreshing variable, or a save-capable variable).
Change your definition to block refreshing such as below, and you should be all set:
a!localVariables( local!username: loggedInUser(), local!time: now(), local!main: a!refreshVariable( value: ri!dictionaryV1.word, refreshAlways: false ), . . . )
Hey Chris, I added this snippet to my code, but its giving me the same error as before on my site
Just to confirm, is this error appearing when you type into the "Search a word" field, or when completing a different action?
Okay so you can check this image that I have attached below, so when I type a word say "king" in my "Search a word" field and click anywhere on the page, nothing happens. But when I click on the Search button, the error pops up.
Gotcha, and that makes since as the interface works as a standalone, but in the site when you are saving back out of the interface, the error appears. This is related to how the rule input for ri!dictionaryv1 is defined when you are calling the interface. Can you share how the interface is called via the site?
Chris said:your definition of local!main will throw this error when you attempt to save into it (it can be only one or the other, a refreshing variable, or a save-capable variable).
AFAIK this is not actually true - it only becomes true when you set the refreshAlways to TRUE (it's false by default). You would, however, run into cases where things behave weirdly when the auto-refresh competes with manual saves.
e.g.
a!localVariables( local!dictionary: { name: "test", id: 1, description: "test 1234 blah" }, local!subValue: local!dictionary.name, a!sectionLayout( label: "test asdf", contents: { a!textField( label: "Name", value: local!dictionary.name, saveInto: local!dictionary.name ), a!textField( label: "local value", instructions: "you can change me, but value will revert when you change the Name field", value: local!subValue, saveInto: local!subValue ) } ) )
Yes sure. Since sites do not allow interfaces with rule inputs, I called my main interface (LCP_searchWordV1) into another interface (say Interface B). So I am using this Interface B as a page on the site.
The code for Interface B is given below:
rule!LCP_searchWordV1 ( dictionaryV1: 'type!{urn:com:appian:types:LCP}LCP_dictionaryV1'(), cancel: false(), readOnly: false() )
Yes this is the cause here, where the interface can't save back into a type definition, it would need a variable to persist the updates to.
dictionaryV1: 'type!{urn:com:appian:types:LCP}LCP_dictionaryV1'()
If this Site Page is setup as a Report, you wouldn't need to send any inputs actually, but it wouldn't do anything outside of the interface..
Assuming this is intended to be used as an Action from a process model Start Form? In which case you would define the interface inputs in the process model via the Properties -> Process Start Form tab.
I have done that as well and hence the reason my process model worked fine when I debugged it
That setup looks correct, is it working properly defined as an Action with the setup in your last screen shot? That appears to be what you need.