6

I managed to get an attribute working in my plugin. Well, sort of. I can read and write the attribute props.attributes.content . But I get the message in the Gutenberg block itself:

Error loading block: Invalid parameter(s): attributes

And in the network inspector I see a 400:

data: {status: 400, params: {attributes: "content is not a valid property of Object."}} params: {attributes: "content is not a valid property of Object."}

enter image description here

Here is the relevant code:

registerBlockType('simpletoc/toc', {
  title: __('SimpleTOC', 'simpletoc'),
  icon: simpletocicon,
  category: 'layout',
  attributes: {
        content: {
            type: 'string',
      source: 'text',
      selector: 'div',
        },
    },
  edit: function(props) {
    props.setAttributes( { content: "newContent" } );
    
    console.info(props.attributes.content);

    const mycontent = props.attributes.content;

    return (
    <div>
    <InspectorControls>
      <ToggleControl
          label={mycontent}
      />
    </InspectorControls>
    <BlockControls>
      <ToolbarGroup>
        <ToolbarButton
          className="components-icon-button components-toolbar__control"
          label={__('Update table of contents', 'simpletoc')}
          onClick={function() {
            sendfakeAttribute(props)
          }}
          icon="update"
        />
      </ToolbarGroup>
  </BlockControls>
  <p className={props.className}>
    <ServerSideRender block={props.name} attributes={props.attributes} />
  </p>
  </div>
    )
  },
  save: props => {
    return null;
  },
});

But I can write the attribute with

props.setAttributes( { content: "newContent" } );

with console.info and my ToggleControl I can actually read the value! What is going on?

1
  • Are you sure there is a defined content attribute at the time of render? You set the attribute in the first line, but that doesn't mean the attribute is instantly updated. It likely means that React will render the component again because the props changed, it may not apply until after rendering. Have you considered setting a default value?
    – Tom J Nowell
    Jan 6, 2021 at 23:15

1 Answer 1

4

The error in question is likely because when you run register_block_type(), you didn't set the block attributes or that it (which is an array in PHP) doesn't have the attribute named content.

So make sure the attributes are defined in both JavaScript (via registerBlockType()) and PHP (via the above-mentioned function), and that the schema is valid. E.g.

  • In JS:

    registerBlockType( 'simpletoc/toc', {
        attributes: {
            content: {
                type: 'string',
                // other args
            },
            // other attributes
        },
        // ...
    } );
    
  • In PHP:

    register_block_type( 'simpletoc/toc', array(
        'attributes' => array(
            'content' => array(
                'type' => 'string',
                // other args
            ),
            // other attributes
        ),
        // ...
    ) );
    
1
  • 2
    Wow. Thank you. It worked.
    – Marc
    Jan 7, 2021 at 9:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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