0

I am trying to create some "cards" to show data from another CPT so I need to store the post ID as part of the block.

The code below has a select in the sidebar which allows you to select the post ID and renders the HTML via a serverSideRender block

and looking at the HTML created and saved and return in the editor reload if has the data (post ID) in the comment block as shown here

<!-- wp:mvc/block-mvc-offer-details {"data_offer":"2426"} /-->

The front-end all works as well and renders the code correctly

But when you reload/re-edit the post the code wipes out the setting and errors the select is not set and no post id is not passed to the server-side code

And the comment gets reset to this without the data ( I can see the correct string in the page source code it gets stripped by JS )

<!-- wp:mvc/block-mvc-offer-details /-->

What have I missed???

/**
 * BLOCK: mvc-landing-pages
 *
 * Registering a basic block with Gutenberg.
 * Simple block, renders and saves the same content without any interactivity.
 */

 //  Import CSS.
 import './editor.scss';
 import './style.scss';

  const {__} = wp.i18n; // Import __() from wp.i18n
  const {registerBlockType} = wp.blocks; // Import registerBlockType() from wp.blocks
  const {InspectorControls} = wp.blockEditor;
  const {Spinner, PanelBody, SelectControl,RangeControl,PanelRow,FormToggle} = wp.components;
  const {withSelect} = wp.data;
  const {Fragment} = wp.element;
  const {serverSideRender: ServerSideRender} = wp;


  /**
   * Register: a Gutenberg Block.
   *
   * Registers a new block provided a unique name and an object defining its
   * behavior. Once registered, the block is made editor as an option to any
  * editor interface where blocks are implemented.
   *
   * @link https://wordpress.org/gutenberg/handbook/block-api/
   * @param  {string}   name     Block name.
   * @param  {Object}   settings Block settings.
   * @return {?WPBlock}          The block, if it has been successfully
   *                             registered; otherwise `undefined`.
   */
  registerBlockType('mvc/block-mvc-offer-details', {
// Block name. Block names must be string that contains a namespace             prefix. Example: my-plugin/my-custom-block.
title: __('MVC Offer details - MVC Block'), // Block title.
icon: 'tickets-alt', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
category: 'mvc-blocks', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.
keywords: [
    __('mvc — CGB Block'),
    __('Attractions'),
],
attributes: {
    data_offer: {
        type: 'number',
    },
},

getEditWrapperProps( props ) {
     console.log(props);
    const { data_offer } = props;
    console.log(data_offer);
    return {
        'data_offer': data_offer,
    };
},
/**
 * The edit function describes the structure of your block in the context of the editor.
 * This represents what the editor will render when the block is used.
 *
 * The "edit" property must be a valid function.
 *
 * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
 *
 *
 * @returns {Mixed} JSX Component.
 */
edit: withSelect(select => {
    return {
        offers: select('core').getEntityRecords('postType', 'offer-landing', {per_page: -1})
        //, fields: ['id', 'name', 'location']
    };
})((props) => {
    let {
        attributes: {data_offer},
        className, setAttributes, offers
    } = props;

    if ( !  offers) {
        return (
            <p className={className}>
                <Spinner/>
                {__('Loading Resorts', 'mvc')}
            </p>
        );
    }

    let options = offers.map(obj => {
        var options = {};
        options = {label: obj.title.rendered, value: obj.id};
        return options;
    });
    options.unshift({label: 'Select Offer', value: null});

    return (<Fragment>
                <InspectorControls>
                    <PanelBody title={__('Offer Settings')} >
                        <PanelRow>
                            <label
                                htmlFor="mvc-offers"
                            >
                                { __( 'Resort', 'mvc' ) }
                            </label>
                            <SelectControl

                                id="mvc-offers"
                                label={__('Offer name', 'mvc')}
                                value={data_offer}
                                onChange={data_offer => setAttributes({data_offer})}
                                options={options}
                            />
                        </PanelRow>
                    </PanelBody>
                </InspectorControls>

                <ServerSideRender block="mvc/block-mvc-offer-details"
                                  attributes={{
                                      data_offer: data_offer,
                                      class_name: className,
                                  }}
                />
            </Fragment>);
}),


/**
 * The save function defines the way in which the different attributes should be combined
 * into the final markup, which is then serialized by Gutenberg into post_content.
 *
 * The "save" property must be specified and must be a valid function.
 *
 * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
 *
 * @param {Object} props Props.
 * @returns {Mixed} JSX Frontend HTML.
 */
save: (props) => {

    return null

},});
1

First thing that jumps out is that in:

<!-- wp:mvc/block-mvc-offer-details {"data_offer":"2426"} /-->

the data_offer value is stored as a string while it's defined attribute type is number.

This could be why it's stripped after reload. While select('core').getEntityRecords does return IDs as integers it's possible that after passing that data to <SelectControl> and then receiving the selected value back by it's onChange(event.target.value) it has lost it's type by being in the DOM.

Try: onChange={data_offer => setAttributes({data_offer: parseInt(data_offer)})}

1
  • that was it :-)
    – Pbearne
    Jan 4 '20 at 17:53
0

You might also like to take a look at the REST API endpoint that handles block rendering for ServerSideRender.

If I understand correctly from your followup post in WP Slack (registration required) you want to pass down a post ID as a block attribute. In that case you need to be sure that you have a matching attribute for "post ID" registered for the block-mvc-offer-details block. This is because the REST API endpoint attributes argument calls get_attributes() as it expects the attributes to match those registered on the block.

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.