Skip to content

fix(data-objectstack): charts blank due to missing rows envelope handling in aggregate()#1162

Merged
hotlong merged 2 commits intomainfrom
copilot/fix-charts-rendering-issue
Apr 1, 2026
Merged

fix(data-objectstack): charts blank due to missing rows envelope handling in aggregate()#1162
hotlong merged 2 commits intomainfrom
copilot/fix-charts-rendering-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 1, 2026

The rawRows extraction chain in aggregate() never checked for data.rows or data.data.rows, so it always fell through to []. The analytics API (/api/v1/analytics/query) returns { rows, fields, sql } — either directly (SDK unwraps the outer envelope) or nested under data — neither of which was handled.

Changes

  • packages/data-objectstack/src/index.ts — Extend rawRows chain with data.rows and data.data.rows checks:
const rawRows: any[] = Array.isArray(data) ? data
  : data?.rows && Array.isArray(data.rows) ? data.rows           // SDK unwraps → { rows, fields, sql }
  : data?.data && Array.isArray(data.data) ? data.data
  : data?.data?.rows && Array.isArray(data.data.rows) ? data.data.rows  // full envelope → { data: { rows } }
  : data?.results && Array.isArray(data.results) ? data.results
  : [];
  • packages/data-objectstack/src/aggregate.test.ts — Two new test cases covering both response shapes ({ rows } and { data: { rows } }), including verification that measure keys (e.g. expected_revenue_sum) are correctly remapped to field names (expected_revenue).

  • CHANGELOG.md — Updated analytics entry to note this follow-up fix.

Original prompt

Problem

Issue #1160 was partially fixed — the aggregate() method in packages/data-objectstack/src/index.ts now correctly sends measures as a string array (e.g. ['expected_revenue_sum']), so the backend no longer throws t.split is not a function. However, charts still render blank because the response extraction logic does not handle the actual response shape returned by the analytics API.

Actual API Response

The analytics API (/api/v1/analytics/query) returns data in this envelope:

{
  "success": true,
  "data": {
    "rows": [
      { "stage": "closed_won", "expected_revenue_sum": 225000 },
      { "stage": "negotiation", "expected_revenue_sum": 36000 },
      { "stage": "proposal", "expected_revenue_sum": 51000 },
      { "stage": "prospecting", "expected_revenue_sum": 50000 },
      { "stage": "qualification", "expected_revenue_sum": 14000 },
      { "stage": "closed_lost", "expected_revenue_sum": 0 }
    ],
    "fields": [
      { "name": "stage", "type": "string" },
      { "name": "expected_revenue_sum", "type": "number" }
    ],
    "sql": "..."
  }
}

The @objectstack/client SDK's analytics.query() method likely unwraps the { success, data } outer envelope, returning { rows: [...], fields: [...], sql: "..." } to the caller.

Current Extraction Logic (Broken)

In packages/data-objectstack/src/index.ts, lines 851-854:

const rawRows: any[] = Array.isArray(data) ? data           // ❌ data is { rows, fields, sql } — not an array
  : data?.data && Array.isArray(data.data) ? data.data      // ❌ data.data doesn't exist at this level
  : data?.results && Array.isArray(data.results) ? data.results  // ❌ no .results property
  : [];                                                     // ⬅️ Falls through to EMPTY ARRAY!

The chain never checks for data.rows, which is the actual property containing the row data. This means rawRows is always [], so the chart receives empty data and renders blank.

If the SDK does NOT unwrap the outer envelope, then the shape would be { success: true, data: { rows: [...] } }, and the chain checks data.data which is { rows, fields, sql } — also not an array, so it still falls through to [].

Required Fix

Update the rawRows extraction chain in the aggregate() method to handle all known response shapes, including the rows property:

const rawRows: any[] = Array.isArray(data) ? data
  : data?.rows && Array.isArray(data.rows) ? data.rows
  : data?.data && Array.isArray(data.data) ? data.data
  : data?.data?.rows && Array.isArray(data.data.rows) ? data.data.rows
  : data?.results && Array.isArray(data.results) ? data.results
  : [];

Files to Modify

  1. packages/data-objectstack/src/index.ts — Fix the rawRows extraction in aggregate() method (around line 851)
  2. packages/data-objectstack/src/aggregate.test.ts — Add test cases for the rows response envelope:
    • Test: analytics.query() returns { rows: [...] } (SDK unwraps outer envelope)
    • Test: analytics.query() returns { data: { rows: [...] } } (SDK does not unwrap)
    • Verify both correctly extract rows and map measure keys back to field names
  3. CHANGELOG.md — Update the existing analytics entry to note the additional fix for the rows response envelope

Acceptance Criteria

  • Given the API returns { success: true, data: { rows: [...], fields: [...] } }, charts should receive the correct data array
  • Existing tests for data, results, and direct array responses must continue to pass
  • New tests cover the rows and data.rows envelope patterns
  • The measure key mapping (expected_revenue_sumexpected_revenue) must still work correctly after extraction

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: 评估当前任务的进展,目前接口不报错了,但是前端图表显示为空白。参考以下接口输入:{"cube":"opportunity","measures":["expected_revenue_sum"],"dimensions":["stage"]}
返回 : {
"success": true,
"data": {
"rows": [
{
"stage": "closed_won",
"expected_revenue_sum": 225000
},
{
"stage": "negotiation",
"expected_revenue_sum": 36000
},
{
"stage": "proposal",
"expected_revenue_sum": 51000
},
{
"stage": "prospecting",
"expected_revenue_sum": 50000
},
{
"stage": "qualification",
"expected_revenue_sum": 14000
},
{
"stage": "closed_lost",
"expected_revenue_sum": 0
}
],
"fields": [
{
"name": "stage",
"type": "string"
},
{
"name": "expected_revenue_sum",
"type": "number"
}
],
"...

This pull request was created from Copilot chat.

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectui-demo Ready Ready Preview, Comment Apr 1, 2026 2:18am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectui Ignored Ignored Apr 1, 2026 2:18am

Request Review

Copilot AI changed the title [WIP] Fix charts rendering blank due to response extraction logic fix(data-objectstack): charts blank due to missing rows envelope handling in aggregate() Apr 1, 2026
Copilot AI requested a review from hotlong April 1, 2026 02:21
@hotlong hotlong marked this pull request as ready for review April 1, 2026 02:29
Copilot AI review requested due to automatic review settings April 1, 2026 02:29
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes blank chart rendering by updating @object-ui/data-objectstack’s aggregate() response parsing to correctly extract analytics rows from the API’s { rows } / { data: { rows } } envelopes, and adds unit tests to prevent regressions.

Changes:

  • Extend aggregate()’s rawRows extraction to handle { rows: [...] } and { data: { rows: [...] } } response shapes.
  • Add two unit tests covering both envelope variants and confirming measure-key remapping (e.g. expected_revenue_sumexpected_revenue).
  • Update the changelog entry to document the follow-up fix for blank charts.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
packages/data-objectstack/src/index.ts Adds data.rows / data.data.rows handling so analytics query results don’t incorrectly fall through to [].
packages/data-objectstack/src/aggregate.test.ts Adds test coverage for both analytics response envelopes and validates measure-key remapping still works.
CHANGELOG.md Documents the additional envelope-handling fix as part of the analytics aggregate entry.

@hotlong hotlong merged commit 4b8ac8e into main Apr 1, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants