Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using getDefaultFormState with 'default' and 'const' values to override current formData #4251

Open
1 task done
Bonfims opened this issue Jul 15, 2024 · 2 comments
Open
1 task done

Comments

@Bonfims
Copy link

Bonfims commented Jul 15, 2024

Prerequisites

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?

@Bonfims Bonfims added needs triage Initial label given, to be assigned correct labels and assigned question labels Jul 15, 2024
@Bonfims
Copy link
Author

Bonfims commented Jul 16, 2024

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!

@nickgros
Copy link
Contributor

@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!

@nickgros nickgros added awaiting response defaults and removed needs triage Initial label given, to be assigned correct labels and assigned labels Jul 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants