2

I am using wp.data.dispatch('core/editor').editpost to try and save an object as a value into post meta. I keep getting an error saying. "Updating failed. firstName is not a valid property of Object" Here is a simple example of what I am trying.

Register post meta

            $post_type = ''; 
            register_post_meta( $post_type, '_example_meta_key', [
                'auth_callback' => function() {
                    return current_user_can('edit_posts');
                },
                'show_in_rest'      => true,
                'single'            => true,
                'type'              => 'object',
            ]);

In js file:

 let person = {
      firstName: 'John',
      lastName: 'Doe'
    };
wp.data.dispatch('core/editor').editPost({ meta: { _example_meta_key: person } })

I have added a new settings section using 'PluginDocumentSettingPanel' hook which captures the user input for the meta.

When I save the page I get an error in the page "Updating failed. firstName is not a valid property of Object."

I am sure it is something simple, but I can't get it to work.

Thanks.

1 Answer 1

1

As stated in the Object Meta Type section of the Modifying Responses page in the REST API Handbook:

When registering object meta, setting the type to object is not sufficient, you also need to inform WordPress of what properties to allow. This is done by writing a JSON Schema when registering the metadata.

Interestingly, register_meta() will throw an error if you register an array type without a schema, but it doesn't seem to perform this check for the object type. I'm not clear on why.

The schema format is an adaptation of the JSON Schema Version 4 specification, with a couple deviations.

In this case, a schema to describe an object such as { firstName: 'John', lastName: 'Doe' } might look as such:

register_post_meta( $post_type, '_example_meta_key', [
  'auth_callback' => function() {
    return current_user_can('edit_posts');
  },
  'show_in_rest'  => [
    'schema' => [
      'type'       => 'object',
      'properties' => [
        'firstName' => [
          'type' => 'string',
        ],
        'lastName'  => [
          'type' => 'string',
        ],
      ],
    ],
  ],
  'single'       => true,
  'type'         => 'object',
]);

Also note that when registering meta for a post type for use in REST API interactions, it is required that the post type has custom-fields support. While you can use an empty string to address all available post types, when interacting with meta for a post over the REST API (such as through Gutenberg APIs), the operation will fail if the post's post type does not support custom-fields.

Addendum: Dynamic Properties Schema

If you're unsure of what the keys of your properties will be or how many there might be, you can use the additionalProperties keyword in the object schema to specify a schema for all other properties which are not otherwise addressed.

The object type supports a number of additional keywords and constraints to further define an object's schema as well.

In the case described in the comments, a schema to describe the object

{
  default_profile: { isRestricted: true },
  profile_one: { isRestricted: true },
  profile_two: { isRestricted: true },
}

with unknown "profile names" / an unknown number of profile entries could be written as such:

  'show_in_rest'  => [
    'schema' => [
      'type'                 => 'object',
      'additionalProperties' => [
        'type'       => 'object',
        'properties' => [
          'isRestricted' => [
            'type' => 'boolean',
          ],
        ],
      ],
    ],
  ],

4
  • Thanks. I was just messing with the schema aspect when I saw your reply. I got it to work, but now I have a more complex schema that has me stumped. How do I configure this scheme ` let access = { default_profile: { isRestricted: true }, profile_one: { isRestricted: true }, profile_two: { isRestricted: true } }; wp.data.dispatch('core/editor').editPost({ meta: { _example_meta_key: access } })` The 'profile_one' and 'profile_two' are dynamically created based on what a user names the profile. So it could be any name. How would I configure the schema? Aug 25, 2022 at 14:12
  • 1
    Yeah, sorry! I misread that the first time through - I've corrected the example :)
    – bosco
    Aug 25, 2022 at 14:27
  • Thanks, I figured that you misread it. The example makes more sense. I will have to try it later and get back to you. I owe you for all the help Aug 25, 2022 at 14:29
  • That worked. Need to do further testing, but I think it is what I need. Thanks again @bosco Aug 25, 2022 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.