I use Gutenberg with WordPress and I would like to check some fields before the user publish his post.
I would like to check if the featured image
, the title
and a simple text field
in a meta-box are not empty.
If a field is empty a notification is displayed and I locked the "Publish" button.
For the moment all works fine with the featured image
and the title
. But when I'm trying to check is the text field in the meta-box is empty I got errors :
Uncaught TypeError: Cannot read property '_myprefix_text_metafield' of undefined
I created my meta-box with a text field like that :
import { __ } from '@wordpress/i18n';
import { useSelect, useDispatch } from '@wordpress/data';
import { registerPlugin } from '@wordpress/plugins';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { TextControl } from '@wordpress/components';
const TextController = (props) => {
const meta = useSelect(
(select) =>
select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']
);
const { editPost } = useDispatch('core/editor');
return (
<TextControl
label={__("Text Meta", "textdomain")}
value={meta}
onChange={(value) => editPost({ meta: { _myprefix_text_metafield: value } })}
/>
);
};
const PluginDocumentSettingPanelDemo = () => (
<PluginDocumentSettingPanel name="text-presentation" title="Texte de présentation" className="custom-panel custom-panel-presentation" icon=" ">
<TextController />
</PluginDocumentSettingPanel>
);
registerPlugin('plugin-document-setting-panel-demo', {
render: PluginDocumentSettingPanelDemo
});
And to check if all fields are not empty :
const locks = [];
function lock( lockIt, handle, message ) {
if ( lockIt ) {
if ( ! locks[ handle ] ) {
locks[ handle ] = true;
wp.data.dispatch( 'core/editor' ).lockPostSaving( handle );
wp.data.dispatch( 'core/notices' ).createNotice(
'error',
message,
{ id: handle, isDismissible: false }
);
}
} else if ( locks[ handle ] ) {
locks[ handle ] = false;
wp.data.dispatch( 'core/editor' ).unlockPostSaving( handle );
wp.data.dispatch( 'core/notices' ).removeNotice( handle );
}
}
wp.data.subscribe( () => {
// get presentation
const textPresentation = wp.data.select( 'core/editor' ).getEditedPostAttribute('meta')['_myprefix_text_metafield'];
// Lock the post if the presentation is empty.
lock(
! textPresentation,
'presentation-lock',
'Please add a presentation text',
);
// get the current title
const postTitle = wp.data.select( 'core/editor' ).getEditedPostAttribute( 'title' );
// Lock the post if the title is empty.
lock(
! postTitle,
'title-lock',
'Please add a title',
);
// get the Featured Image
const featuredImage = wp.data.select( 'core/editor' ).getEditedPostAttribute( 'featured_media' );
// Lock post if there is no Featured Image selected
lock(
featuredImage === 0,
'featured-image-lock',
'Please add a featured image',
);
});
When I write this in the console :
wp.data.select( 'core/editor' ).getEditedPostAttribute('meta')['_myprefix_text_metafield'];
The value returned well the value of my text field.
That could happen when the XHR/AJAX request that fetches post data from the REST API hasn't been fully resolved, so you can't simply access the metadata like that. You need to ensure that getEditedPostAttribute('meta')
actually returns an object and only then access the _myprefix_text_metafield
property.
So try with this instead:
const textPresentation = wp.data.select( 'core/editor' ) // wrapped for brevity
.getEditedPostAttribute( 'meta' )?._myprefix_text_metafield;
// Lock the post if the presentation is empty.
lock(
undefined !== textPresentation && ! textPresentation,
'presentation-lock',
'Please add a presentation text'
);