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

useDefaults requires explicit empty object for intermediate object entries to work for nested properties #1710

Closed
skyboyer opened this issue Jul 22, 2021 · 1 comment

Comments

@skyboyer
Copy link

skyboyer commented Jul 22, 2021

What version of Ajv you are you using?
6.12.5 but also tried with 8.6.2

What problem do you want to solve?
Assume we have definition with nested objects:

const schema = {
  type: "object",
  properties: {
    a: {
      type: "object",
      properties: {
        b: {
          type: "string",
          default: "123"
        }
      }
    },
    c: {
      type: "string",
      default: "456"
    }
  }
};

Then we want to init data with default values:

const data = {};
const ajv = new Ajv({ useDefaults: true });
ajv.compile(schema)(data);

This processes only first-level properties and gives {"c":"456"}. To get {"a":{"b":"123"},"c":"456"} it's required to add explicit default: {} to every entry with type of "object" like

const schema = {
  type: "object",
  properties: {
    a: {
      type: "object",
      default: {},
      properties: {
        b: {
          type: "string",
          default: "123"
        }
      }
    },
    c: {
      type: "string",
      default: "456"
    }
  }
};

But with this approach, if we try to inject default: {} in every object just in sake of nested properties, we might end with empty objects in our data:

const schema = {
  type: "object",
  properties: {
    a: {
      type: "object",
      default: {},
      properties: {
        b: {
          type: "string", // no "default:"!
        },
      },
    },
  }
};

will give us { a: {} } while I expect to get {}.

What do you think is the correct solution to problem?
I think that ability to init defaults in deep without need to explicitly declare default: {} on every object would add flexibility. Checked JSON schema 7.0 docs and don't see any way approach contradicts how "default" is worked(well, docs are actually about validation instead of generating data but still).

Will you be able to implement it?
If everything above makes sense, I'm ready.

@epoberezkin
Copy link
Member

Given that the schema is iterated top - down properties of missing objects are never reached for their defaults to used…

Any solution would be quite complex, while adding defaults for objects is quite simple.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants