1

In a plugin I'm building for Gutenberg, I register a meta field named _related_posts, which stores an array of post ids:

PHP:

function register_meta_fields() {
    register_post_meta( '', '_related_posts', array(
        'show_in_rest' => true,
        'single'       => true,
        'type'         => 'array',
        'show_in_rest' => array(
            'schema' => array(
                'type'  => 'array',
                'items' => array(
                    'type' => 'integer',
                ),
            ),
        ),
        'auth_callback' => function() {
            return current_user_can( 'edit_posts' );
        }
    ) );
}

I'm using the useEntityProp hook to get and set this meta field in JS:

JS:

const [ meta, setMeta ] = useEntityProp(
    'postType',
    'post',
    'meta'
);

I have a onUpdateRelatedPosts() function that gets called when the user selects a post from a list:

JS:

function onUpdateRelatedPosts( post ) {
    setMeta( { ...meta, '_related_posts': [post.id] } );
}

This function takes a post object as an argument and stores its id in the _related_posts meta field, but I can't get it to work as I want. It doesn't append the id at the end of the array but replaces the whole meta field with the added id.

What am I doing wrong?

1 Answer 1

1

When you do this: '_related_posts': [post.id], you're actually overriding the entire array or the meta value, so to instead append an item to the existing array, you can use the spread (...) syntax like so: '_related_posts': [ ...meta._related_posts, post.id ].

But you may not want to update the meta if the selected post ID is already in the current meta value, i.e.

// Add the post (ID) if it's not already in the list.
if ( meta._related_posts.indexOf( post.id ) < 0 ) {
    setMeta( { ...meta, '_related_posts': [ ...meta._related_posts, post.id ] } );
}

That's just a suggestion (to avoid duplicate values), though.

And BTW, for property names that do not contain characters that are not alphanumeric or underscore (_), it's not mandatory to enclose the property name in quotes. So for example in your case, _related_posts: (as opposed to having the quotes: '_related_posts':) would be fine. :)

2
  • 1
    Thank you for posting the id duplicate check code in addition to the answer to my question. Very appreciated.
    – leemon
    May 27, 2021 at 13:08
  • I deleted my previous comment, but anyway, thank you for the edit, @hgodinho :)
    – Sally CJ
    Apr 27, 2022 at 10:02

Your Answer

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

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