diff --git a/client/helpers/ajax.js b/client/helpers/ajax.js index 75cf0601..9e212ef1 100644 --- a/client/helpers/ajax.js +++ b/client/helpers/ajax.js @@ -1,3 +1,5 @@ +import { JSONStringify } from "./form"; + export function http_get(url, type = "json", params) { return new Promise((done, err) => { const xhr = new XMLHttpRequest(); @@ -50,7 +52,7 @@ export function http_post(url, data, type = "json", params) { xhr.withCredentials = true; xhr.setRequestHeader("X-Requested-With", "XmlHttpRequest"); if (data && type === "json") { - data = JSON.stringify(data); + data = JSONStringify(data); xhr.setRequestHeader("Content-Type", "application/json"); } if (params && params.progress) { diff --git a/client/helpers/form.js b/client/helpers/form.js index 4221d3fd..61a02b1f 100644 --- a/client/helpers/form.js +++ b/client/helpers/form.js @@ -99,3 +99,28 @@ export function autocomplete(values, list) { .replace(/\,\s?$/, ""); }); } + +export function JSONStringify(data) { + return JSON.stringify(data, (key, value) => { + if (value === null) return; + else if (value === undefined) return; + else if (value === "") return; + else if (Array.isArray(value)) return value; + else if (typeof(value) === "string") return value; + else if (typeof(value) === "number") return value; + else if (typeof(value) === "boolean") return value; + else if (typeof(value) === "object") { + const tmp = Object.values(value); + if (tmp.length === 0) return; + if (tmp.filter((n) => { + if(JSON.stringify(n) === "{}") return false; + else if(n === null) return false; + return true; + }).length === 0) return; + return value; + } + const msg = `[BUG] unknown stringify value (helpers/form.js): ${value}`; + console.error(msg); + throw new Error(msg); + }); +} diff --git a/client/helpers/index.js b/client/helpers/index.js index 878a28ed..f5b11a87 100644 --- a/client/helpers/index.js +++ b/client/helpers/index.js @@ -19,5 +19,5 @@ export { gid, randomString } from "./random"; export { leftPad, format, copyToClipboard, objectGet, nop } from "./common"; export { getMimeType } from "./mimetype"; export { settings_get, settings_put } from "./settings"; -export { FormObjToJSON, createFormBackend, autocomplete } from "./form"; +export { FormObjToJSON, createFormBackend, autocomplete, JSONStringify } from "./form"; export { upload } from "./upload"; diff --git a/client/pages/adminpage/backend.js b/client/pages/adminpage/backend.js index 85ac1368..d82314ad 100644 --- a/client/pages/adminpage/backend.js +++ b/client/pages/adminpage/backend.js @@ -1,7 +1,7 @@ import React, { useState, useEffect } from "react"; import { FormBuilder, Icon, Input, Alert, Loader } from "../../components/"; import { Backend, Config, Middleware } from "../../model/"; -import { FormObjToJSON, notify, format, createFormBackend, objectGet } from "../../helpers/"; +import { FormObjToJSON, notify, format, createFormBackend, objectGet, JSONStringify } from "../../helpers/"; import { t } from "../../locales/"; import "./backend.scss"; @@ -136,7 +136,7 @@ export class BackendPage extends React.Component { const { type, ...other } = objectGet(middlewareData, ["identity_provider"]) || {}; return { "type": type || null, - "params": JSON.stringify(other), + "params": JSONStringify(other), }; })(), "attribute_mapping": (function() { @@ -145,9 +145,7 @@ export class BackendPage extends React.Component { "related_backend": related_backend || "N/A" }; if(Object.keys(params).length > 0) { - obj.params = JSON.stringify(params, (key, value) => { - if (value !== null) return value - }); + obj.params = JSONStringify(params); } return obj; })(),