Skip to content

Conversation

rahulbarwal
Copy link
Contributor

@rahulbarwal rahulbarwal commented Jun 6, 2025

Description

Problem

Errors appeared in the console when the List widget in edit mode received an empty array as data.

Root cause

In edit mode, the List widget uses template widgets to create meta widgets. When the list becomes empty, meta widgets are not generated, but template widgets with currentItem bindings remain. Since currentItem requires meta widgets for evaluation, this results in errors.

Solution

This PR handles the generation of empty meta widgets when the List widget receives empty data, ensuring currentItem bindings don’t break. It introduces a generateEmptyMetaWidgets method in MetaWidgetGenerator, enhances the List widget to track and respond to empty data states, and resets the meta widget cache when transitioning between empty and non-empty states.

Fixes #Issue Number
or
Fixes #31925

Warning

If no issue exists, please create an issue first, and check with the maintainers if the issue is valid.

Automation

/ok-to-test tags="@tag.List"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/15756809644
Commit: 58818e0
Cypress dashboard.
Tags: @tag.List
Spec:


Thu, 19 Jun 2025 12:11:58 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of empty list data on the first page, ensuring widgets display correctly when no data is present.
    • Enhanced consistency in detecting and rendering empty lists across the List Widget.
  • New Features

    • Added a utility function to accurately identify fully empty lists, enabling more predictable widget behavior.
    • Introduced an option to handle empty list cases by injecting placeholder data for consistent widget generation.
  • Tests

    • Added a test to verify the display of "No data to display" message when the list is empty and confirm no errors occur.

…scenarios

Added functionality to generate empty meta widgets when the list data is empty, preventing currentItem binding errors. This includes creating meta widgets with the same IDs as template widgets and ensuring safe currentItem bindings. Updated ListWidget to manage transitions between empty and non-empty data states effectively.

- Introduced `generateEmptyMetaWidgets` method in MetaWidgetGenerator.
- Enhanced ListWidget to track empty data state and generate meta widgets accordingly.
- Added logic to reset meta widget cache when transitioning from empty to non-empty data.

This improves the robustness of the ListWidget in handling dynamic data scenarios.
Copy link
Contributor

coderabbitai bot commented Jun 6, 2025

Walkthrough

The changes introduce a unified approach for handling empty list data in the ListWidgetV2 component. A new utility function determines if the list is fully empty on the first page, influencing how meta widgets are generated and rendered. The logic for empty data handling is now centralized and consistently applied across relevant modules.

Changes

File(s) Change Summary
app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts Modified addCurrentItemProperty to handle a special empty data case; removed private method resetCache; added isEmptyListWidgetCase flag.
app/client/src/widgets/ListWidgetV2/widget/helper.ts Added new exported utility function isListFullyEmpty for centralized empty list detection.
app/client/src/widgets/ListWidgetV2/widget/index.tsx Integrated isListFullyEmpty in meta widget generation and rendering logic; updated imports and comments.
app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_BasicClientSideData_spec.js Added new test verifying "No data to display" message and no errors when list items are empty.
app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts Updated tests to explicitly set isEmptyListWidgetCase option to false for consistency.

Sequence Diagram(s)

sequenceDiagram
    participant UI
    participant ListWidget
    participant Helper as isListFullyEmpty
    participant MetaWidgetGen

    UI->>ListWidget: Render ListWidget (with listData, pageNo)
    ListWidget->>Helper: isListFullyEmpty(listData, pageNo)
    Helper-->>ListWidget: true/false
    alt List is fully empty
        ListWidget->>MetaWidgetGen: Generate meta widgets with [{}]
    else
        ListWidget->>MetaWidgetGen: Generate meta widgets with listData
    end
    MetaWidgetGen-->>ListWidget: Meta widgets
    ListWidget-->>UI: Rendered widget view
Loading

Poem

In the land where lists may dwindle,
A helper checks if data's simple.
If empty, a placeholder appears,
Ensuring widgets have no fears.
Meta magic, logic neat,
Empty lists now feel complete!
🎩✨


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f2d986a and 58818e0.

📒 Files selected for processing (1)
  • app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts (4 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: rahulbarwal
PR: appsmithorg/appsmith#40886
File: app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts:1115-1134
Timestamp: 2025-06-13T07:49:21.417Z
Learning: For ListWidgetV2, an empty array supplied by users is internally converted to `[{}]` (a placeholder row) when `pageNo === 1`; this sentinel is never produced by user data, so a singleton empty object on page 1 can be safely treated as “empty list” in MetaWidgetGenerator.
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: perform-test / server-build / server-unit-tests
  • GitHub Check: perform-test / rts-build / build
  • GitHub Check: client-check-cyclic-deps / check-cyclic-dependencies
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-prettier / prettier-check
  • GitHub Check: client-build / client-build
🔇 Additional comments (1)
app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.test.ts (1)

170-170: LGTM! Proper test compatibility update for the new empty list feature.

The explicit addition of isEmptyListWidgetCase: false across test cases correctly maintains existing behavior while accommodating the new empty list widget handling functionality. This ensures backward compatibility and prevents test regressions.

Also applies to: 854-854, 902-902

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@rahulbarwal
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions github-actions bot added the Enhancement New feature or request label Jun 6, 2025
@rahulbarwal rahulbarwal requested a review from ashit-rath June 6, 2025 11:38
Copy link

github-actions bot commented Jun 6, 2025

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/15489666321.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 40886.
recreate: .

@rahulbarwal rahulbarwal added the ok-to-test Required label for CI label Jun 6, 2025
Copy link

github-actions bot commented Jun 6, 2025

Deploy-Preview-URL: https://ce-40886.dp.appsmith.com

…ta handling

Eliminated the `generateEmptyMetaWidgets` method and related logic from the `MetaWidgetGenerator` and `ListWidget` components. The handling of empty data scenarios is now managed directly within the `generateMainMetaCanvasWidget` method, ensuring that an empty object is added to `listData` when it is empty. This simplifies the codebase and improves the efficiency of meta widget generation.

- Removed redundant methods and properties related to empty meta widget generation.
- Updated `ListWidget` to directly handle empty data cases without relying on separate meta widget generation logic.
- Enhanced clarity and maintainability of the code by consolidating data handling logic.
Updated the logic for handling empty data cases in the ListWidget and MetaWidgetGenerator. The check for empty data now considers the current page number to prevent generating empty meta widgets when navigating to a page with no data. Introduced a new helper function, isListFullyEmpty, to encapsulate this logic for better readability and maintainability.
@rahulbarwal rahulbarwal marked this pull request as ready for review June 13, 2025 07:35
@rahulbarwal rahulbarwal requested a review from a team as a code owner June 13, 2025 07:35
@rahulbarwal rahulbarwal requested review from jacquesikot and removed request for a team June 13, 2025 07:35
@github-actions github-actions bot added Bug Something isn't working Community Reported issues reported by community members List Widget Issues related to the list widget Medium Issues that frustrate users due to poor UX Needs Triaging Needs attention from maintainers to triage Production Query Widgets & IDE Pod All issues related to Query, JS, Eval, Widgets & IDE Widgets & Accelerators Pod Issues related to widgets & Accelerators Widgets Product This label groups issues related to widgets and removed Bug Something isn't working labels Jun 13, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (1)
app/client/src/widgets/ListWidgetV2/widget/index.tsx (1)

566-575: 🛠️ Refactor suggestion

Avoid mutating props.listData – clone instead

push mutates the array that comes straight from props, violating React’s immutability expectations and risks subtle bugs when this method is called multiple times.

-    if (isListFullyEmpty(listData, pageNo)) {
-      listData.push({});
-    }
+    const processedListData = isListFullyEmpty(listData, pageNo)
+      ? [{}]        // placeholder for empty-data meta generation
+      : listData.slice();   // shallow clone keeps later logic untouched

and later use processedListData instead of listData in the return object.

This avoids side-effects, keeps renders deterministic and prevents accidentally appending multiple placeholders if the binding re-evaluates to [].

🧹 Nitpick comments (2)
app/client/src/widgets/ListWidgetV2/widget/helper.ts (1)

133-140: Guard against undefined inputs & favour immutability

isListFullyEmpty will throw if listData is undefined (e.g. listData?: unknown[]) and silently returns false when pageNo is undefined. A tiny defensive tweak avoids both cases without changing semantics.

-export const isListFullyEmpty = (listData: unknown[], pageNo: number) => {
+export const isListFullyEmpty = (
+  listData: unknown[] | undefined,
+  pageNo: number | undefined,
+) => {
   ...
-  return listData.length === 0 && pageNo === 1;
+  return Array.isArray(listData) && listData.length === 0 && pageNo === 1;
};
app/client/src/widgets/ListWidgetV2/widget/index.tsx (1)

46-50: Nit: grouped helper imports improve readability

With three helpers coming from the same module, prefer a single import line:

-import {
-  getMetaFlexLayers,
-  isListFullyEmpty,
-  isTargetElementClickable,
-} from "./helper";
+import { getMetaFlexLayers, isListFullyEmpty, isTargetElementClickable } from "./helper";
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 126f557 and 9a3f801.

📒 Files selected for processing (3)
  • app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts (1 hunks)
  • app/client/src/widgets/ListWidgetV2/widget/helper.ts (1 hunks)
  • app/client/src/widgets/ListWidgetV2/widget/index.tsx (4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/client/src/widgets/ListWidgetV2/widget/index.tsx (1)
app/client/src/widgets/ListWidgetV2/widget/helper.ts (1)
  • isListFullyEmpty (133-140)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-build / client-build
🔇 Additional comments (1)
app/client/src/widgets/ListWidgetV2/widget/index.tsx (1)

1471-1474: Empty-state logic now always returns “not empty”

After injecting the placeholder [{}], isListFullyEmpty inevitably returns false, so the empty-state component will never render.
Double-check that this UX change is intended; if you still want to display “No data to display” you need a different predicate (e.g. originalDataWasEmpty flag).

Refactored the empty data handling logic in the ListWidget by removing the dependency on the isListFullyEmpty function. The check for empty data now solely relies on filtering the listData array, enhancing clarity and maintainability of the code. This change ensures that the widget correctly identifies and handles empty data scenarios without unnecessary complexity.
@github-actions github-actions bot added Bug Something isn't working and removed Bug Something isn't working labels Jun 13, 2025
@rahulbarwal
Copy link
Contributor Author

/build-deploy-preview skip-tests=true

Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/15629332705.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 40886.
recreate: .

Copy link

Deploy-Preview-URL: https://ce-40886.dp.appsmith.com

Implemented a new test case to verify that when the List widget is provided with empty data, it correctly displays a "No data to display" message and ensures no errors are logged in the Appsmith console. This enhances the robustness of the List widget's empty state handling.
@github-actions github-actions bot added the Bug Something isn't working label Jun 13, 2025
Updated the test case for the List widget to ensure that when provided with empty data, it correctly displays the "No data to display" message and verifies that no errors are logged in the Appsmith console. This change improves the robustness of the widget's handling of empty states.
@github-actions github-actions bot removed the Bug Something isn't working label Jun 13, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_BasicClientSideData_spec.js (1)

171-174: Selector is brittle; prefer a data-attribute over visible text

AssertElementVisibility(_.locators._visibleTextDiv("No data to display")) hard-codes UI copy. Any wording tweak will break the test while functionality remains intact. Expose an explicit data-cy (e.g. data-cy="list-empty-state") on the empty-state wrapper and assert against that:

-_.agHelper.AssertElementVisibility(
-  _.locators._visibleTextDiv("No data to display"),
-);
+_.agHelper.AssertElementVisibility('[data-cy="list-empty-state"]');

This follows Appsmith’s Cypress guidelines (data-* selectors, no raw strings) and keeps the spec resilient to copy changes.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 164614c and e37fb41.

📒 Files selected for processing (1)
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_BasicClientSideData_spec.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`app/client/cypress/**/**.*`: Review the following e2e test code written using the Cypress test library. Ensure that: - Follow best practices for Cypress code and e2e automation. ...

app/client/cypress/**/**.*: Review the following e2e test code written using the Cypress test library. Ensure that:

  • Follow best practices for Cypress code and e2e automation.
  • Avoid using cy.wait in code.
  • Avoid using cy.pause in code.
  • Avoid using agHelper.sleep().
  • Use locator variables for locators and do not use plain strings.
  • Use data-* attributes for selectors.
  • Avoid Xpaths, Attributes and CSS path.
  • Avoid selectors like .btn.submit or button[type=submit].
  • Perform logins via API with LoginFromAPI.
  • Perform logout via API with LogOutviaAPI.
  • Perform signup via API with SignupFromAPI.
  • Avoid using it.only.
  • Avoid using after and aftereach in test cases.
  • Use multiple assertions for expect statements.
  • Avoid using strings for assertions.
  • Do not use duplicate filenames even with different paths.
  • Avoid using agHelper.Sleep, this.Sleep in any file in code.
  • app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_BasicClientSideData_spec.js
🧠 Learnings (1)
📓 Common learnings
Learnt from: rahulbarwal
PR: appsmithorg/appsmith#40886
File: app/client/src/widgets/ListWidgetV2/MetaWidgetGenerator.ts:1115-1134
Timestamp: 2025-06-13T07:49:21.394Z
Learning: For ListWidgetV2, an empty array supplied by users is internally converted to `[{}]` (a placeholder row) when `pageNo === 1`; this sentinel is never produced by user data, so a singleton empty object on page 1 can be safely treated as “empty list” in MetaWidgetGenerator.
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: perform-test / client-build / client-build
  • GitHub Check: client-unit-tests / client-unit-tests
  • GitHub Check: client-lint / client-lint
  • GitHub Check: client-build / client-build
🔇 Additional comments (1)
app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_BasicClientSideData_spec.js (1)

169-169:

❌ Incorrect review comment

"[]" is set as a string, not a JS array

UpdatePropertyFieldValue("Items", "[]") injects literal text. If the property pane is in string mode, the list gets the characters [], not an empty array, and the test passes only because the binding still parses to an empty-ish value. To avoid an accidental regression, drive the control in JS mode:

-_.propPane.UpdatePropertyFieldValue("Items", "[]");
+_.propPane.UpdatePropertyFieldValue("Items", "{{[]}}");

This guarantees you’re testing the real empty-array path instead of relying on lenient coercion.


🏁 Script executed:

#!/bin/bash
# Locate the definition and usages of UpdatePropertyFieldValue to verify its behavior
rg "UpdatePropertyFieldValue" -n
rg "propPane" -n

Length of output: 73089


🏁 Script executed:

#!/bin/bash
# Display the UpdatePropertyFieldValue method implementation for verification
sed -n '380,430p' app/client/cypress/support/Pages/PropertyPane.ts

Length of output: 1800


🏁 Script executed:

#!/bin/bash
# Find definition of UpdateCodeInput in the agHelper
rg "UpdateCodeInput" -n app/client/cypress/support/Pages

Length of output: 747


🏁 Script executed:

#!/bin/bash
# Show context around line 169 for Listv2_BasicClientSideData_spec.js
sed -n '150,200p' app/client/cypress/e2e/Regression/ClientSide/Widgets/ListV2/Listv2_BasicClientSideData_spec.js

Length of output: 899


Ignore wrapping the empty array in {{…}}
The ListV2 “Items” field is a JSON/code editor by default, so calling

_.propPane.UpdatePropertyFieldValue("Items", "[]");

already injects an actual empty-array expression. No JS-toggle or mustache braces are needed here.

Likely an incorrect or invalid review comment.

Updated the isListFullyEmpty function to accept an undefined listData parameter and return false if listData is not provided. Adjusted the ListWidget to use the updated function, ensuring it checks for the presence of data before attempting to push an empty object. This improves the robustness of the widget's empty state handling.
@github-actions github-actions bot added the Bug Something isn't working label Jun 17, 2025
@rahulbarwal rahulbarwal requested a review from ashit-rath June 18, 2025 09:10
…nerator

### 📝 Summary
This commit introduces a new option `isEmptyListWidgetCase` to the `GeneratorOptions` interface and the `MetaWidgetGenerator` class, enhancing the handling of empty list scenarios in the ListWidget.

### 🎨 Changes Made
- **MetaWidgetGenerator (`MetaWidgetGenerator.ts`)**
  - Added `isEmptyListWidgetCase` to `GeneratorOptions` and initialized it in the constructor.
  - Updated logic to utilize `isEmptyListWidgetCase` for determining empty data cases.

- **ListWidget (`index.tsx`)**
  - Introduced a local variable `isEmptyListWidgetCase` to determine if the list is empty and adjusted the data binding accordingly.

This change improves the robustness of the ListWidget's empty state handling, ensuring it correctly represents empty data scenarios without generating unnecessary meta widgets.
@github-actions github-actions bot removed the Bug Something isn't working label Jun 19, 2025
@rahulbarwal rahulbarwal requested a review from ashit-rath June 19, 2025 11:21
ashit-rath
ashit-rath previously approved these changes Jun 19, 2025
@github-actions github-actions bot added the Bug Something isn't working label Jun 19, 2025
@rahulbarwal rahulbarwal merged commit a801a19 into release Jun 20, 2025
43 checks passed
@rahulbarwal rahulbarwal deleted the rahulbarwal/fix-list-widget-issue branch June 20, 2025 04:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working Community Reported issues reported by community members Enhancement New feature or request List Widget Issues related to the list widget Medium Issues that frustrate users due to poor UX Needs Triaging Needs attention from maintainers to triage ok-to-test Required label for CI Production Query Widgets & IDE Pod All issues related to Query, JS, Eval, Widgets & IDE Widgets & Accelerators Pod Issues related to widgets & Accelerators Widgets Product This label groups issues related to widgets
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: currentItem is not defined in Empty List Widget
2 participants