How to update a meta field of type array in Gutenberg

The question:

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


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:


const [ meta, setMeta ] = useEntityProp(

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


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

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?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

When you do this: '_related_posts': [], 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, ].

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( ) < 0 ) {
    setMeta( { ...meta, '_related_posts': [ ...meta._related_posts, ] } );

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 or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment