How to update a meta field of type array in Gutenberg

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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 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 want 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 enclode the property name in quotes. So for example in your case, _related_posts: (as opposed to having the quotes: '_related_posts':) would be fine. 🙂


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x