react-jsonschema-form
react-jsonschema-form copied to clipboard
Using getDefaultFormState with 'default' and 'const' values to override current formData
Prerequisites
- [X] I have read the documentation
What theme are you using?
core
What is your question?
Hello!
I was trying to achieve an override-like functionality with getDefaultFormState from the utils. For example:
const { validator } = require("...");
let newSchema = {
type: "object",
properties: {
field: {
type: "string",
default: "456",
const: "456"
}
}
};
let currentFormData = { field: 123 };
let formData = getDefaultFormState(validator, newSchema, currentFormData);
// This will return { field: 123 }
I was expecting it to return { field: "456" }, assuming that the schema's property declarations (const, default and readOnly) would override the current value.
Is there a way to achieve this?
Hey,
I endeed up with a combination of getDefaultFormState, sanitizeDataForNewSchema and mergeDefaultsWithFormData:
const { getDefaultFormState, sanitizeDataForNewSchema, mergeDefaultsWithFormData } = require("...");
const { validator } = require("...");
let oldSchema = {
type: "object",
properties: {
field: {
type: "string",
default: "123"
}
}
};
// getting a form data from schema above
let currentFormData = getDefaultFormState(validator, oldSchema, { test: "hello world!" });
// -> { test: "hello world!", field: "123" }
let newSchema = {
type: "object",
properties: {
field: {
type: "string",
default: "456",
const: "456"
}
}
};
// getting default form data value from newSchema
let newFormData = getDefaultFormState(validator, newSchema, {});
// -> { field: "456" }
// so, i want get a override-like that would be -> { test: "hello world!", field: "456" }
// to achive this, i used `sanitizeDataForNewSchema` to clean currentFormData
let sanitized = sanitizeDataForNewSchema(validator, {}, newSchema, oldSchema, currentFormData);
// -> { test: "hello world!", field: undefined }
// now i can merge it with `mergeDefaultsWithFormData`
let finalFormData = mergeDefaultsWithFormData(sanitized, newFormData);
// -> { test: "hello world!", field: "456" }
For now, i will try for this way, let me know if a missing something, thank you!
@Bonfims as you discovered, getDefaultFormState won't overwrite data that has already been filled in. In Form.tsx, we call it regularly because the 'default state' may change dynamically (e.g. if the user is using oneOf/anyOf or if/then/else.
You might have trouble using sanitizeDataForNewSchema in this way since it won't replace default fields where the formData value does not match the oldSchema default value. Depending on your use case, you may need to dynamically manipulate the data or dynamically create a new 'old schema'. You can take a look at the sanitizeDataForNewSchema source, which describes the process to see if it makes sense for your use case.
In any case, clever solution, hopefully it works how you need it to!
This issue has been automatically marked as possibly close because it has not had recent activity. It will be closed if no further activity occurs. Please leave a comment if this is still an issue for you. Thank you.