Error: Could not display interface. Please check definition and inputs. Interface Definition: Expression evaluation error at function a!forEach [line 40]: Error in a!forEach() expression during iteration 1: Expression evaluation error at function a!textField [line 46]: Invalid index: Cannot index property 'SourceDisplayName' of type Text into type Text
Please explain what this means? It seems ambiguous, as it is unable to map a Text type to Text.
Trying to retrieve records from DB with a Query Rule and with foreach trying to display in Editable Grid. The Expression Mode SAIL code is below:
=load( local!sources: rule!CoE_RetrieveAllSources_QueryRule(), a!formLayout( label: "Add/Edit Sources of Technologies", contents: { a!gridLayout( totalCount: count(local!sources), headerCells: { a!gridLayoutHeaderCell(label: "Display Name" ), a!gridLayoutHeaderCell(label: "Full Name" ), a!gridLayoutHeaderCell(label: "Description" ), /* For the "Remove" column */ a!gridLayoutHeaderCell(label: "" ) }, /* Only needed when some columns need to be narrow */ columnConfigs: { a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:3 ), a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:3 ), a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight:5 ), a!gridLayoutColumnConfig(width: "ICON") }, /* * a!forEach() will take local!employee data and used that data to loop through an * expression that creates each row. * * When modifying the recipe to work with your data, you only need to change: * 1.) the number of fields in each row * 2.) the types of fields for each column (i.e. a!textField() for text data elements) * 3.) the fv!item elements. For example fv!item.firstName would change to fv!item.yourdata */ rows: a!forEach( items: local!sources, expression: a!gridRowLayout( contents: { /* For the Last Name Column*/ a!textField( label: "Display Name " & fv!index, value: fv!item.SourceDisplayName, saveInto: fv!item.SourceDisplayName, required:true ), /* For the Department Column*/ a!textField( label: "Full Name " & fv!index, value: fv!item.SourceFullName, saveInto: fv!item.SourceFullName, required:true ), /* For the Title Column*/ a!textField( label: "Description " & fv!index, value: fv!item.SourceDescription, saveInto: fv!item.SourceDescription, required:true ), /* For the Removal Column*/ a!imageField( label: "Remove " & fv!index, images: a!documentImage( document: a!iconIndicator("REMOVE"), altText: "Remove source", caption: "Remove " & fv!item.SourceDisplayName, link: a!dynamicLink( value: fv!index, saveInto: { a!save(local!sources, remove(local!sources, save!value)) } ) ), size: "ICON" ) }, id: fv!index ) ), addRowlink: a!dynamicLink( label: "Add Source", /* * For your use case, set the value to a blank instance of your CDT using * the type constructor, e.g. type!Employee(). Only specify the field * if you want to give it a default value e.g. startDate: today()+1. */ value: { startDate: today() + 1 }, saveInto: { a!save(local!sources, append(local!sources, save!value)) } ) ) }, buttons: a!buttonLayout( primaryButtons: a!buttonWidgetSubmit( label: "Submit" ) ) ))
Discussion posts and replies are publicly visible
You should only use .(dot) operator when you are very very sure that no null value is going to come in your data. For all other cases use index() function to retrieve data.