diff --git a/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte b/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte index 740027a8fd..1e1103dbdb 100644 --- a/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/ExportModal.svelte @@ -1,6 +1,7 @@ diff --git a/packages/server/src/api/controllers/row/external.js b/packages/server/src/api/controllers/row/external.js index 534f2207b0..a44402c5c8 100644 --- a/packages/server/src/api/controllers/row/external.js +++ b/packages/server/src/api/controllers/row/external.js @@ -55,7 +55,8 @@ exports.save = async ctx => { exports.fetchView = async ctx => { // there are no views in external data sources, shouldn't ever be called // for now just fetch - ctx.params.tableId = ctx.params.viewName.split("all_")[1] + const split = ctx.params.viewName.split("all_") + ctx.params.tableId = split[1] ? split[1] : split[0] return exports.fetch(ctx) } diff --git a/packages/server/src/api/controllers/view/exporters.js b/packages/server/src/api/controllers/view/exporters.js index 65b12b48de..0cca3b5f89 100644 --- a/packages/server/src/api/controllers/view/exporters.js +++ b/packages/server/src/api/controllers/view/exporters.js @@ -16,3 +16,8 @@ exports.csv = function (headers, rows) { exports.json = function (headers, rows) { return JSON.stringify(rows, undefined, 2) } + +exports.ExportFormats = { + CSV: "csv", + JSON: "json", +} diff --git a/packages/server/src/api/controllers/view/index.js b/packages/server/src/api/controllers/view/index.js index ecaee0f32f..3b43ef2408 100644 --- a/packages/server/src/api/controllers/view/index.js +++ b/packages/server/src/api/controllers/view/index.js @@ -4,6 +4,7 @@ const { apiFileReturn } = require("../../../utilities/fileSystem") const exporters = require("./exporters") const { saveView, getView, getViews, deleteView } = require("./utils") const { fetchView } = require("../row") +const { getTable } = require("../table/utils") exports.fetch = async ctx => { const db = new CouchDB(ctx.appId) @@ -56,7 +57,7 @@ exports.exportView = async ctx => { const view = await getView(db, viewName) const format = ctx.query.format - if (!format) { + if (!format || !Object.values(exporters.ExportFormats).includes(format)) { ctx.throw(400, "Format must be specified, either csv or json") } @@ -80,10 +81,22 @@ exports.exportView = async ctx => { let schema = view && view.meta && view.meta.schema if (!schema) { const tableId = ctx.params.tableId || view.meta.tableId - const table = await db.get(tableId) + const table = await getTable(ctx.appId, tableId) schema = table.schema } + // make sure no "undefined" entries appear in the CSV + if (format === exporters.ExportFormats.CSV) { + const schemaKeys = Object.keys(schema) + for (let key of schemaKeys) { + for (let row of ctx.body) { + if (row[key] == null) { + row[key] = "" + } + } + } + } + // Export part let headers = Object.keys(schema) const exporter = exporters[format]