BUG in NEW list view on methods available on each component from the 3rd instance in the listview

Hi there,

I am facing a bug in the new list view component, and the methods available to the component inside the list view from the 3rd instance.

The goal of my app is to have 2 textArea within an item of a list view to interact.

Basic setup (see the app below):

  • a list view
  • inside the listview, 2 text area components (textArea1, and textArea2).
  • the textArea1 has an event triggered on change to "Run Script"
  • the "Run Script" just sets the value to textArea2:
console.log(textArea2)
textArea2.setValue(textArea1.value)

There is more to it in my app, but the basic bug setting is that.

When I change the first instance of the list view, it works as intended, but from the 3rd instance onwards I get the error: textArea2.setValue is not a function

Looking at the log when changing the first 2 instances, it looks as expected with the setValue method being available:

value: "test for 1st instance"
id: "textArea2"
formDataKey: "textArea2"
....
setValue: "__RETOOL_JS_API__"
clearValue: "__RETOOL_JS_API__"
...

Looking at the log on the 3rd instance of the list view onwards, the methods of all the instances are bundled into a nonsensical list, and I cannot access the setValue since it is not available anymore directly in the component. It seems to show every single instance method of the listview now with some undefined for some reason (but the value is the correct one in that instance if I prepopulated it before).

0: Object
setValue: "__RETOOL_JS_API__"
clearValue: "__RETOOL_JS_API__"
scrollIntoView: "__RETOOL_JS_API__"
validate: "__RETOOL_JS_API__"
clearValidation: "__RETOOL_JS_API__"
setHidden: "__RETOOL_JS_API__"
setDisabled: "__RETOOL_JS_API__"
resetValue: "__RETOOL_JS_API__"
focus: "__RETOOL_JS_API__"
blur: "__RETOOL_JS_API__"
select: "__RETOOL_JS_API__"
1: Object
setValue: "__RETOOL_JS_API__"
clearValue: "__RETOOL_JS_API__"
scrollIntoView: "__RETOOL_JS_API__"
validate: "__RETOOL_JS_API__"
clearValidation: "__RETOOL_JS_API__"
setHidden: "__RETOOL_JS_API__"
setDisabled: "__RETOOL_JS_API__"
resetValue: "__RETOOL_JS_API__"
focus: "__RETOOL_JS_API__"
blur: "__RETOOL_JS_API__"
select: "__RETOOL_JS_API__"
2: undefined
...
9: undefined
10: Object
...
16: Object
value: "test for prepopulated value in 3rd instance"
id: "textArea2"
formDataKey: "textArea2"
...

Note: I tried to enable the option "Enable instance values," but the buggy behavior remained the same.

image.png

Note 2: The bug is dynamic. After tinkering with the value in the instance above 10-ish, the 3rd instance may start working.

  • App json export:
{"uuid":"9dfa2cdc-1d5a-11ef-8993-5bd7a354526a","page":{"id":279339437,"data":{"appState":"[\"~#iR\",[\"^ \",\"n\",\"appTemplate\",\"v\",[\"^ \",\"isFetching\",false,\"plugins\",[\"~#iOM\",[\"listView1\",[\"^0\",[\"^ \",\"n\",\"pluginTemplate\",\"v\",[\"^ \",\"id\",\"listView1\",\"uuid\",\"dcbdbcdc-063f-42b6-bb37-fa121d3042f4\",\"type\",\"widget\",\"subtype\",\"ListViewWidget2\",\"namespace\",null,\"resourceName\",null,\"resourceDisplayName\",null,\"template\",[\"^3\",[\"heightType\",\"auto\",\"layoutType\",\"list\",\"hidden\",false,\"data\",\"[\\\"Fluffy\\\", \\\"Whiskers\\\", \\\"Fido\\\", \\\"Mittens\\\", \\\"Rex\\\", \\\"Snowball\\\", \\\"Spot\\\", \\\"Lucky\\\", \\\"Princess\\\", \\\"Buddy\\\", \\\"Milo\\\", \\\"Cleo\\\", \\\"Lola\\\", \\\"Simba\\\", \\\"Rocky\\\", \\\"Ginger\\\", \\\"Spike\\\", \\\"Max\\\", \\\"Cupcake\\\", \\\"Oreo\\\"]\",\"maxHeight\",\"\",\"margin\",\"0\",\"showInEditor\",false,\"padding\",\"0\",\"formDataKey\",\"{{ self.id }}\",\"itemWidth\",\"200px\",\"primaryKeyFieldNameOverride\",\"\",\"_primaryKeys\",\"\",\"numColumns\",3,\"instanceValues\",null,\"enableInstanceValues\",false,\"overflowType\",\"scroll\",\"_enabledInstances\",null,\"maintainSpaceWhenHidden\",false,\"direction\",\"vertical\"]],\"style\",[\"^3\",[]],\"position2\",[\"^0\",[\"^ \",\"n\",\"position2\",\"v\",[\"^ \",\"^5\",\"grid\",\"container\",\"\",\"rowGroup\",\"body\",\"subcontainer\",\"\",\"row\",0.2,\"col\",0,\"height\",1,\"width\",12,\"tabNum\",0,\"stackPosition\",null]]],\"mobilePosition2\",null,\"mobileAppPosition\",null,\"tabIndex\",null,\"^=\",\"\",\"createdAt\",\"~m1716946071722\",\"updatedAt\",\"~m1716946123888\",\"folder\",\"\",\"screen\",null]]],\"container1\",[\"^0\",[\"^ \",\"n\",\"pluginTemplate\",\"v\",[\"^ \",\"id\",\"container1\",\"^4\",\"778f07f0-c945-47e8-9a54-bb59045614f2\",\"^5\",\"widget\",\"^6\",\"ContainerWidget2\",\"^7\",null,\"^8\",null,\"^9\",null,\"^:\",[\"^3\",[\"_disabledByIndex\",[\"~#iL\",[\"\"]],\"heightType\",\"auto\",\"currentViewKey\",null,\"iconByIndex\",[],\"clickable\",false,\"_iconByIndex\",[\"^K\",[\"\"]],\"headerPadding\",\"4px 12px\",\"showFooterBorder\",true,\"enableFullBleed\",false,\"showBorder\",true,\"hidden\",false,\"showHeader\",true,\"hoistFetching\",false,\"margin\",\"4px 8px\",\"views\",[],\"showInEditor\",false,\"tooltipText\",\"\",\"padding\",\"12px\",\"hiddenByIndex\",[],\"_hiddenByIndex\",[\"^K\",[\"\"]],\"currentViewIndex\",null,\"_hasMigratedNestedItems\",true,\"transition\",\"none\",\"showHeaderBorder\",true,\"footerPadding\",\"4px 12px\",\"itemMode\",\"static\",\"_tooltipByIndex\",[\"^K\",[\"\"]],\"tooltipByIndex\",[],\"showFooter\",false,\"_viewKeys\",[\"^K\",[\"View 1\"]],\"events\",[\"^3\",[]],\"_ids\",[\"^K\",[\"37f82\"]],\"viewKeys\",[],\"iconPositionByIndex\",[],\"_iconPositionByIndex\",[\"^K\",[\"\"]],\"hovered\",false,\"loading\",false,\"overflowType\",\"scroll\",\"disabled\",false,\"_labels\",[\"^K\",[\"\"]],\"disabledByIndex\",[],\"maintainSpaceWhenHidden\",false,\"showBody\",true,\"labels\",[]]],\"^;\",[\"^3\",[]],\"^<\",[\"^0\",[\"^ \",\"n\",\"position2\",\"v\",[\"^ \",\"^5\",\"grid\",\"^=\",\"listView1\",\"^>\",\"body\",\"^?\",\"\",\"row\",0,\"col\",0,\"^@\",1,\"^A\",12,\"^B\",0,\"^C\",null]]],\"^D\",null,\"^E\",null,\"^F\",null,\"^=\",\"\",\"^G\",\"~m1716946071726\",\"^H\",\"~m1716946071726\",\"^I\",\"\",\"^J\",null]]],\"containerTitle1\",[\"^0\",[\"^ \",\"n\",\"pluginTemplate\",\"v\",[\"^ \",\"id\",\"containerTitle1\",\"^4\",\"0fa4261a-f698-44e2-9879-6e1a8d784736\",\"^5\",\"widget\",\"^6\",\"TextWidget2\",\"^7\",null,\"^8\",null,\"^9\",null,\"^:\",[\"^3\",[\"heightType\",\"auto\",\"horizontalAlign\",\"left\",\"hidden\",false,\"imageWidth\",\"fit\",\"margin\",\"4px 8px\",\"showInEditor\",false,\"verticalAlign\",\"center\",\"tooltipText\",\"\",\"value\",\"#### {{ item }}\",\"disableMarkdown\",false,\"overflowType\",\"scroll\",\"maintainSpaceWhenHidden\",false]],\"^;\",[\"^3\",[]],\"^<\",[\"^0\",[\"^ \",\"n\",\"position2\",\"v\",[\"^ \",\"^5\",\"grid\",\"^=\",\"container1\",\"^>\",\"header\",\"^?\",\"\",\"row\",0,\"col\",0,\"^@\",0.6,\"^A\",12,\"^B\",0,\"^C\",null]]],\"^D\",null,\"^E\",null,\"^F\",null,\"^=\",\"\",\"^G\",\"~m1716946071729\",\"^H\",\"~m1716946071729\",\"^I\",\"\",\"^J\",null]]],\"$main\",[\"^0\",[\"^ \",\"n\",\"pluginTemplate\",\"v\",[\"^ \",\"id\",\"$main\",\"^4\",null,\"^5\",\"frame\",\"^6\",\"Frame\",\"^7\",null,\"^8\",null,\"^9\",null,\"^:\",[\"^3\",[\"type\",\"main\",\"sticky\",null,\"padding\",\"8px 12px\",\"enableFullBleed\",false,\"isHiddenOnDesktop\",false,\"isHiddenOnMobile\",false]],\"^;\",[\"^3\",[]],\"^<\",null,\"^D\",null,\"^E\",null,\"^F\",null,\"^=\",\"\",\"^G\",\"~m1716946071733\",\"^H\",\"~m1716946071733\",\"^I\",\"\",\"^J\",null]]],\"textArea1\",[\"^0\",[\"^ \",\"n\",\"pluginTemplate\",\"v\",[\"^ \",\"id\",\"textArea1\",\"^4\",\"ac17cef4-b9ab-45df-8912-a4c75e4f7230\",\"^5\",\"widget\",\"^6\",\"TextAreaWidget\",\"^7\",null,\"^8\",null,\"^9\",null,\"^:\",[\"^3\",[\"spellCheck\",false,\"readOnly\",false,\"autoResize\",true,\"showCharacterCount\",false,\"autoComplete\",false,\"maxLength\",null,\"hidden\",false,\"customValidation\",\"\",\"hideValidationMessage\",false,\"minLines\",2,\"validationMessage\",\"\",\"margin\",\"4px 8px\",\"showInEditor\",false,\"pattern\",\"\",\"tooltipText\",\"\",\"labelAlign\",\"left\",\"formDataKey\",\"{{ self.id }}\",\"value\",\"\",\"labelCaption\",\"\",\"labelWidth\",\"33\",\"autoFill\",\"\",\"placeholder\",\"Enter value\",\"label\",\"Label\",\"_validate\",false,\"labelWidthUnit\",\"%\",\"invalid\",false,\"minLength\",null,\"inputTooltip\",\"\",\"events\",[\"^K\",[[\"^3\",[\"event\",\"change\",\"type\",\"script\",\"method\",\"run\",\"pluginId\",\"\",\"targetId\",null,\"params\",[\"^3\",[\"src\",\"console.log(textArea2)\\ntextArea2.setValue(textArea1.value)\"]],\"waitType\",\"debounce\",\"waitMs\",\"0\"]]]],\"autoCapitalize\",\"none\",\"maxLines\",null,\"loading\",false,\"disabled\",false,\"labelPosition\",\"top\",\"labelWrap\",false,\"maintainSpaceWhenHidden\",false,\"required\",false]],\"^;\",[\"^3\",[]],\"^<\",[\"^0\",[\"^ \",\"n\",\"position2\",\"v\",[\"^ \",\"^5\",\"grid\",\"^=\",\"container1\",\"^>\",\"body\",\"^?\",\"37f82\",\"row\",0.2,\"col\",0,\"^@\",1,\"^A\",4,\"^B\",0,\"^C\",null]]],\"^D\",null,\"^E\",null,\"^F\",null,\"^=\",\"\",\"^G\",\"~m1716946108266\",\"^H\",\"~m1716946152649\",\"^I\",\"\",\"^J\",null]]],\"textArea2\",[\"^0\",[\"^ \",\"n\",\"pluginTemplate\",\"v\",[\"^ \",\"id\",\"textArea2\",\"^4\",\"d4af44b8-1f2a-4982-82b6-893a641558cf\",\"^5\",\"widget\",\"^6\",\"TextAreaWidget\",\"^7\",null,\"^8\",null,\"^9\",null,\"^:\",[\"^3\",[\"spellCheck\",false,\"readOnly\",false,\"autoResize\",true,\"showCharacterCount\",false,\"autoComplete\",false,\"maxLength\",null,\"hidden\",false,\"customValidation\",\"\",\"hideValidationMessage\",false,\"minLines\",2,\"validationMessage\",\"\",\"margin\",\"4px 8px\",\"showInEditor\",false,\"pattern\",\"\",\"tooltipText\",\"\",\"labelAlign\",\"left\",\"formDataKey\",\"{{ self.id }}\",\"value\",\"\",\"labelCaption\",\"\",\"labelWidth\",\"33\",\"autoFill\",\"\",\"placeholder\",\"Enter value\",\"label\",\"Label\",\"_validate\",false,\"labelWidthUnit\",\"%\",\"invalid\",false,\"minLength\",null,\"inputTooltip\",\"\",\"events\",[\"^3\",[]],\"autoCapitalize\",\"none\",\"maxLines\",null,\"loading\",false,\"disabled\",false,\"labelPosition\",\"top\",\"labelWrap\",false,\"maintainSpaceWhenHidden\",false,\"required\",false]],\"^;\",[\"^3\",[]],\"^<\",[\"^0\",[\"^ \",\"n\",\"position2\",\"v\",[\"^ \",\"^5\",\"grid\",\"^=\",\"container1\",\"^>\",\"body\",\"^?\",\"37f82\",\"row\",1.2000000000000002,\"col\",0,\"^@\",1,\"^A\",4,\"^B\",0,\"^C\",null]]],\"^D\",null,\"^E\",null,\"^F\",null,\"^=\",\"\",\"^G\",\"~m1716946111259\",\"^H\",\"~m1716946111259\",\"^I\",\"\",\"^J\",null]]]]],\"^G\",null,\"version\",\"3.57.0\",\"appThemeId\",null,\"appThemeName\",null,\"appMaxWidth\",\"100%\",\"preloadedAppJavaScript\",null,\"preloadedAppJSLinks\",[],\"testEntities\",[],\"tests\",[],\"appStyles\",\"\",\"responsiveLayoutDisabled\",false,\"loadingIndicatorsDisabled\",false,\"urlFragmentDefinitions\",[\"^K\",[]],\"pageLoadValueOverrides\",[\"^K\",[]],\"customDocumentTitle\",\"\",\"customDocumentTitleEnabled\",false,\"customShortcuts\",[],\"isGlobalWidget\",false,\"isMobileApp\",false,\"isFormApp\",false,\"shortlink\",null,\"multiScreenMobileApp\",false,\"mobileAppSettings\",[\"^ \",\"mobileOfflineModeEnabled\",false,\"mobileOfflineModeDelaySync\",false,\"mobileOfflineModeBannerMode\",\"default\",\"displaySetting\",[\"^ \",\"landscapeMode\",false,\"tabletMode\",false]],\"formAppSettings\",[\"^ \",\"customRedirectUrl\",\"\"],\"notificationsSettings\",[\"^ \",\"globalQueryShowFailureToast\",true,\"globalQueryShowSuccessToast\",false,\"globalQueryToastDuration\",4.5,\"globalToastPosition\",\"bottomRight\"],\"folders\",[\"^K\",[]],\"pageCodeFolders\",[\"^ \"],\"queryStatusVisibility\",false,\"markdownLinkBehavior\",\"auto\",\"inAppRetoolPillAppearance\",\"NO_OVERRIDE\",\"rootScreen\",null,\"instrumentationEnabled\",false,\"experimentalFeatures\",[\"^ \",\"sourceControlTemplateDehydration\",false,\"multiplayerEditingEnabled\",false,\"disableMultiplayerEditing\",false],\"experimentalDataTabEnabled\",true,\"customComponentCollections\",[],\"savePlatform\",\"web\",\"internationalizationSettings\",[\"^ \",\"internationalizationEnabled\",false,\"internationalizationFiles\",[]]]]]"},"changesRecord":[{"type":"WIDGET_TEMPLATE_UPDATE","payload":{"plugin":{"id":"textArea1","type":"widget","uuid":"ac17cef4-b9ab-45df-8912-a4c75e4f7230","style":{},"folder":"","subtype":"TextAreaWidget","template":{"label":"Label","value":"","events":[{"type":"script","event":"change","method":"run","params":{},"waitMs":"0","pluginId":"","waitType":"debounce"}],"hidden":false,"margin":"4px 8px","invalid":false,"loading":false,"pattern":"","autoFill":"","disabled":false,"maxLines":null,"minLines":2,"readOnly":false,"required":false,"_validate":false,"labelWrap":false,"maxLength":null,"minLength":null,"autoResize":true,"labelAlign":"left","labelWidth":"33","spellCheck":false,"formDataKey":"{{ self.id }}","placeholder":"Enter value","tooltipText":"","autoComplete":false,"inputTooltip":"","labelCaption":"","showInEditor":false,"labelPosition":"top","autoCapitalize":"none","labelWidthUnit":"%","customValidation":"","validationMessage":"","showCharacterCount":false,"hideValidationMessage":false,"maintainSpaceWhenHidden":false},"container":"","createdAt":"2024-05-29T01:28:28.266Z","position2":{"col":0,"row":0.2,"type":"grid","width":4,"height":1,"tabNum":0,"rowGroup":"body","container":"container1","subcontainer":"37f82","stackPosition":null},"updatedAt":"2024-05-29T01:29:07.355Z"},"update":{"events":[{"type":"script","event":"change","method":"run","params":{"src":"console.log(textArea2)\ntextArea2.setValue(textArea1.value)"},"waitMs":"0","pluginId":"","waitType":"debounce"}]},"widgetId":"textArea1","shouldRecalculateTemplate":true},"isUserTriggered":true}],"gitSha":null,"checksum":null,"createdAt":"2024-05-29T01:29:10.868Z","updatedAt":"2024-05-29T01:29:10.868Z","pageId":3176526,"userId":330742,"branchId":null,"page":{"name":"Jon Go - May 29, 2024 - 1:27:34PM"}},"modules":{}}

Anyone from Retool?

Hi @jo_n_go, I was able to reproduce this bug so I created the workaround I'll share below. When I tried reproducing it one more time, to include the app in the internal bug report, I did not run into the issue again (no releases happened in those 10 min).

To avoid your app from breaking, in case this issue is happening inconsistently, take this approach:

Instead of referencing the input.value directly, which seems to be causing the issue, we'll use a State variable to store the data for the second text area.

The initial value could be anything, but let's use an empty object to keep data integrity:

On the first "Text Area" component, set event handler to update the state variable:


Here is the JS for you to copy if needed:

ListViewData.setValue({...ListViewData.value, [i]: textArea1.value})

This will only update the key in the object with the index of the input. Because we are using repeatable components, the indices will always match (the repeatable with the index of 0 has the "textArea1" with the index of 0, and so on).

On the other hand, for second text area, set the default value to:

{{ListViewData.value[i]}}

Just like the object gets populated correctly because of the matching indices, the values will also match the with correct key in the object using i.

Let us know if you have any questions!

Hi Paulo,

I can confirm that the bug is still there. Please retry.

Appreciate the workaround, but it is not working well enough.

I tried it in my app, but I run in another issue of the state variable data becoming out of sync if several changes happen too fast (other component interact with those fields in my app, including checkboxes). I believe it is due to the async nature of the setValue and the fact that it is visibly slower to interact with the state variable.

A fix on the main issue would still be appreciated.

Jon

Thanks for the update, I'll create the bug report and include that it may happen inconsistently. We'll update you when this is fixed. On the meantime, you could add await before the setValue invocations but as you mentioned, it may slow down the UI.

Could you do me a favor and upload the App JSON export as an attachment here? That way I can include your App in the report.

1 Like

We should be able to add a Debounce of 500ms to the event handler so the setValue only runs when the user stops typing. That should fix the out of sync issue.

I am reproducing this bug today. I've added await to the setValue() call.

However, it seems very specifically related to the index, not the timing.

The first two list elements work consistently. Third and above fail consistently. Even if I start fresh, the third element fails.

I have a button action to reset the value of an edited text edit view.

console.log("Reset", fieldEdit.value, fieldEdit)
await fieldEdit.setValue(item.orig)

Another suspicious aspect is that fieldEdit.value does print out on failures. The error is:

Error:fieldEdit.setValue is not a function. (In 'fieldEdit.setValue(item.orig)', 'fieldEdit.setValue' is undefined)

Digging a little deeper, it looks like it's indexes 2-9 of the array that are undefined! I confirmed that 10 works as expected. I don't have a theory yet explaining why it's those indexes in particular...

Hi @jmontrose, I'm unable to reproduce this issue on cloud. The following event handler works like a charm:

Adding a button to reset back to " " in my case works as well:

Do you have a button that removes or adds items to the List View?

The same applies when resetting the child of another repeatable (index 4):

Interesting. No, I don't, but let me try to make a minimal reproduction myself, I figured this was a known issue when I saw someone else hitting the third element :slight_smile:

1 Like

I started from scratch and recreated this in what I hope is a small-enough repro. (Forgive the multi-page, I was preparing to demo different repro cases)

Thanks for looking into this, and let me know if I can help with debugging.

ListBoxMystery.json is attached.

Walkthrough:

  • variable dataset drives the fields, with the original values
  • editField starts out with value from dataset
  • resetButton is hidden if editField.value == item.orig
  • resetButton.click calls editField.setValue(item.orig)

Behavior:

  • Click reset of a to change 999 to 1
  • Click reset of f fails: editField.setValue is not a function

Expected:

  • Click reset of f should set it to 6

Also note in the console log that elements 2-9 of the internal editField array are undefined. Confusing that it's always these indexes!

ListBoxMystery.json (11.4 KB)

Thank you for sharing your app and repro steps! Although I'm not sure why objects 2-9 are showing as undefined when you log editField, here is how we can fix it:

Change the event handler to control the component instead of running the script, then reference the original value from the State variable:

Here is the fixed version:
ListBoxMystery (1).json (12.4 KB)