I am trying to extend the core/image
block by pulling in the media description field and use its contents as an extra attribute. I am currently stuck with getting a Rest API call with wp.data.select('core').getMedia(id)
inside the BlockEdit filter HOC to work. Whatever I've tried so far ("directly" using select
like in example code below or a useSelect
hook it always results in the same error "TypeError: select(...).getMedia(...) is undefined"
. I am successfully using core block extensions for other functionality as well as many different select calls in other custom blocks. I am importing select
and useSelect
from the wp.data
package and I have set my dependencies in the plugins PHP.
Here's my code (relevant parts):
Top of script
const { select, useSelect } = wp.data;
const restrictTo = ['core/image'];
BlockEdit HOC – wrapping image block's Edit function
const withDescription = createHigherOrderComponent((BlockEdit) => {
return (props) => {
const {name, attributes, setAttributes, isSelected} = props;
if ( isSelected && restrictTo.includes(name) ) {
const {id} = attributes;
// id will be available when image is chosen from the inserter
if (id) {
/* doesn't work, yields error described above, even with useSelect hook */
const desc = select('core').getMedia(id).description.raw;
}
//
}
return (
<Fragment>
<BlockEdit {...props} />
<Inspector Controls stuff...>
</Fragment>
)
};
}, 'withDescription');
Filter
addFilter('editor.BlockEdit','vortac/with-description',withDescription);
I have already searched for articles and help covering a similar problem and found this from the wordpress.org support forums: https://wordpress.org/support/topic/how-to-use-wp-data-select-in-blocklist/
@jorgefilipecosta is referencing a piece of Core code that is actually using select
in a HOC. It's a different BlockFilter editor.BlockListBlock though
, but I don't think this should make a difference.
Thanks in advance for your help.
I have finally found the mistake in my code. Using select
in the BlockEdit
filter HOC is not the actual problem, as I assumed when posting the question. The select
call itself in the form of const desc = select('core').getMedia(id).description.raw;
is not correct. I suppose it doesn't work because the select
call yields a promise and until a value is loaded for .getMedia()
it is not possible to access the field description
, resulting in the error I originally described in my question. So here's the actual simple solution in my final implementation using the useSelect
hook (again just the relevant parts):
const { select, useSelect } = wp.data;
const restrictTo = [ 'core/image' ];
const withDescription = createHigherOrderComponent( ( BlockEdit ) => {
return ( props ) => {
const { name, attributes, setAttributes, isSelected } = props;
if ( isSelected && restrictTo.includes( name ) ) {
const { id } = attributes;
// an image id will be available as soon as an image is chosen from the inserter
if ( id ) {
const tmpDesc = useSelect( ( select ) => {
return select( 'core' ).getMedia( id );
}, [ id ] );
// if a value for tmpDesc is set its raw description will be accessible
const desc = ( tmpDesc ) ? tmpDesc[ 'description' ][ 'raw' ] : '';
}
//
}
return (
<Fragment>
<BlockEdit {...props} />
<Inspector Controls stuff...>
</Fragment>
)
};
}, 'withDescription');
addFilter('editor.BlockEdit','vortac/with-description',withDescription);