diff --git a/examples/components/widgets/table-widget.ts b/examples/components/widgets/table-widget.ts
index 1e180b1..f400101 100644
--- a/examples/components/widgets/table-widget.ts
+++ b/examples/components/widgets/table-widget.ts
@@ -67,7 +67,7 @@ export class TableWidget extends BaseWidget {
return widgetSource.getTable({
columns,
...(sortBy && {sortBy, sortDirection}),
- rowsPerPage: limit,
+ limit,
spatialFilter: this.getSpatialFilterOrViewState(),
});
},
@@ -132,6 +132,17 @@ function renderTableBody(response: TableResponse) {
function renderTableRow(row: unknown[]) {
return html`
- ${map(row, (value) => html`${value} | `)}
+ ${map(row, renderTableCell)}
`;
}
+
+const _numberFormatter = new Intl.NumberFormat();
+function renderTableCell(value: unknown) {
+ let formattedValue: string;
+ if (typeof value === 'number') {
+ return _numberFormatter.format(value);
+ } else {
+ formattedValue = String(value);
+ }
+ return html`${formattedValue} | `;
+}
diff --git a/src/sources/widget-base-source.ts b/src/sources/widget-base-source.ts
index 25b8bf9..0b3d787 100644
--- a/src/sources/widget-base-source.ts
+++ b/src/sources/widget-base-source.ts
@@ -258,8 +258,9 @@ export abstract class WidgetBaseSource {
},
opts: {abortController},
}).then((res: TableModelResponse) => ({
- rows: normalizeObjectKeys(res.rows),
- totalCount: res.metadata.total,
+ // Avoid `normalizeObjectKeys()`, which changes column names.
+ rows: res.rows ?? (res as any).ROWS,
+ totalCount: res.metadata?.total ?? (res as any).METADATA?.TOTAL,
}));
}
diff --git a/test/sources/widget-base-source.test.ts b/test/sources/widget-base-source.test.ts
index d7ffc6f..92ddfe8 100644
--- a/test/sources/widget-base-source.test.ts
+++ b/test/sources/widget-base-source.test.ts
@@ -346,6 +346,53 @@ test('getTable', async () => {
});
});
+test('getTable - snowflake', async () => {
+ const widgetSource = new WidgetTestSource({
+ accessToken: '',
+ connectionName: 'carto_dw',
+ });
+
+ const expectedRows = [
+ {name: 'Veggie Mart', rEVenUe: 1200},
+ {name: 'EZ Drive Thru', rEVenUe: 400},
+ {name: "Buddy's Convenience", rEVenUe: 800},
+ ];
+
+ // NOTICE: Snowflake returns uppercase keys.
+ const mockFetch = vi
+ .fn()
+ .mockResolvedValueOnce(
+ createMockResponse({ROWS: expectedRows, METADATA: {TOTAL: 3}})
+ );
+ vi.stubGlobal('fetch', mockFetch);
+
+ const actualTable = await widgetSource.getTable({
+ columns: ['name', 'revenue'],
+ limit: 20,
+ offset: 10,
+ });
+
+ expect(mockFetch).toHaveBeenCalledOnce();
+ expect(actualTable).toEqual({
+ rows: expectedRows,
+ totalCount: 3,
+ });
+
+ const params = new URL(mockFetch.mock.lastCall[0]).searchParams.entries();
+ expect(Object.fromEntries(params)).toMatchObject({
+ type: 'test',
+ source: 'test-data',
+ params: JSON.stringify({
+ column: ['name', 'revenue'],
+ limit: 20,
+ offset: 10,
+ }),
+ queryParameters: '',
+ filters: JSON.stringify({}),
+ filtersLogicalOperator: 'and',
+ });
+});
+
/******************************************************************************
* getScatter
*/