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:
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?
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': [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