2

I am trying use <FocalPointPicker /> in <PluginDocumentSettingPanel /> and almost everything working as it should, but I have troubles when creating a new post. I am getting this warning:

Warning: Received NaN for the value attribute.

As I understand it occur because post meta isn't created yet. I solved this by adding update_post_meta during post creation. But I think there should be a better solution using pure React.

This is my code:

// in init.php
add_action('init','register_my_post_meta');
function register_my_post_meta() {
    $args_img = array(
        'type' => 'object',
        'single' => true,
        'show_in_rest' => array(
            'schema' => array(
                'type'  => 'object',
                'properties' => array(
                        'url' => array(
                        'type' => 'url',
                    ),
                        'width' => array(
                        'type' => 'number',
                    ),
                        'height' => array(
                        'type' => 'number',
                    ),
                        'id' => array(
                        'type' => 'number',
                    ),
                ),
            ),
        ),
    );

    $args_focal = array(
        'type' => 'object',
        'single' => true,
        'show_in_rest' => array(
            'schema' => array(
                'type'  => 'object',
                'properties' => array(
                        'x' => array(
                        'type' => 'number',
                    ),
                        'y' => array(
                        'type' => 'number',
                    ),
                ),
            ),
        ),
    );
    register_post_meta( '', 'img', $args_img );
    register_post_meta( '', 'focalPoint', $args_focal );
}
// in index.js
const { registerPlugin } = wp.plugins;
const { PluginDocumentSettingPanel } = wp.editPost;
const { withSelect, withDispatch } = wp.data;
const { MediaUpload, MediaUploadCheck } = wp.blockEditor;
const { Button, FocalPointPicker } = wp.components;



let PhotoControl = ({img, focalPoint, handleImgChange, handleFocalChange}) =>(
  <MediaUploadCheck>
    {!!img["url"] &&
      <FocalPointPicker
        url={ img["url"] }
        value={ focalPoint }
        onChange={ focalPoint => handleFocalChange(focalPoint)}
      />
    }
    {!img["url"] &&
      <MediaUpload
         title="My Image"
         onSelect={
           img => handleImgChange(img)
         }
         allowedTypes={['image']}
         value={ img }
         render= { ( { open } ) => (
            <Button
             id={'image-upload'}
             onClick={open}>
                 { ! img["url"] && "upload image" }
            </Button>
         ) }
     />
    }
  </MediaUploadCheck
);

PhotoControl = withSelect(
  (select) => {
      return {
          img: select('core/editor').getEditedPostAttribute('meta')['img'],
          focalPoint: select('core/editor').getEditedPostAttribute('meta')['focalPoint']
      }
  }
)(PhotoControl);

PhotoControl = withDispatch(
  (dispatch) => {
      return {
          handleImgChange: (value) => {
              dispatch('core/editor').editPost({ meta: { img:{
                "url": value.url,
                "width": value.width,
                "height": value.height,
                "id": value.id
              } })
          }
          handleFocalChange: (value) => {
              dispatch('core/editor').editPost({ meta: { focalPoint: value } })
          }
      }
  }
)(PhotoControl);

const PluginWithFocalpoint = () => {
  return(
    <PluginDocumentSettingPanel>
      <PhotoControl />
    </PluginDocumentSettingPanel>

  );
}
registerPlugin( 'plugin-with-focalpoint', { render: PluginWithFocalpoint, icon: ' ' } );

And here my temporary solution:

// in init.php
function create_meta_for_new_posts($post_id, $post, $update) {
    if (empty(get_post_meta( $post_id, 'focalPoint' ))) {
        update_post_meta( $post_id, 'focalPoint', array("x"=>0.5,"y"=>0.5) );
    }
}
add_action( 'wp_insert_post', 'create_meta_for_new_posts', 10, 3 );
0

Ok, I found the solution by myself. Inside withSelect it is needed to assign default value if getEditedPostAttribute is empty.

// Helper function to check if received meta object is empty or not
function isEmpty(obj) {
  for(var key in obj) {
      if(obj.hasOwnProperty(key))
          return false;
  }
  return true;
}

PhotoControl = withSelect(
  (select) => {
      let myFocal = select('core/editor').getEditedPostAttribute('meta')['focalPoint'];
      if(isEmpty(myFocal)) { focal={ "x": 0.5, "y": 0.5 }; } // Solution is here. If is empty object assign default values.
      return {
          img: select('core/editor').getEditedPostAttribute('meta')['img'],
          focalPoint: myFocal
      }
  }
)(PhotoControl);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.