DanieleAlessandra
DanieleAlessandra

Reputation: 1555

Gutenberg block validation fails (missing attribute)

I made a Gutenberg block for my plugin but it doesn't work as expected anymore. It worked with the first version of Gutenberg and I don’t understand what changed since then.

I read some similar questions, but no useful answers: - Wordpress Gutenberg block - Gutenberg Block validation failed - Gutenberg Block Validation Failed ( not expecting children )

My problem in detail:

When I add the block into my content it looks perfect, also if I save the post I see the widget as expected.

The problem is that when I edit an existing article the block is broken: https://ibb.co/6vHRcXC

The code looks good, I can see it in code editor: https://ibb.co/tDMGnPY

Updating the article the widget still works on frontend.

The console shows this warning followed by several errors: https://ibb.co/Gk80skq

It looks like the attribute data-id is missing in generated code, but I don't understand why.

I tried changing this attribute name (in case [data-id] was a reserved word) but nothing changed.

I tried changing the value of this attribute (I need it to be an integer, but I tried adding uppercase, lowercase and underscore prefixes) and nothing changed.

A bit of context: I need a unique ID for every block created with Gutenberg, no repetitions site wide and I need to bring this ID to a JavaScript function on frontend. Please tell me what I am doing wrong and if there is another way to accomplish that.

This is the complete JavaScript source of my Gutenberg block:

(function () {

    let iconSvg = wp.element.createElement('svg', {width: 20, height: 20},
        wp.element.createElement('path', {d: "M10,0C4.478,0,0,4.478,0,10c0,5.521,4.478,10,10,10c5.521,0,10-4.479,10-10C20,4.478,15.521,0,10,0zM5.039,9.226c-0.786,0-1.425,0.765-1.425,1.705H2.576c0-1.512,1.104-2.742,2.462-2.742s2.463,1.23,2.463,2.742H6.463C6.463,9.991,5.825,9.226,5.039,9.226z M10,18.049c-3.417,0-6.188-2.41-6.188-5.382h12.375C16.188,15.639,13.418,18.049,10,18.049zM16.387,10.931c0-0.94-0.639-1.705-1.426-1.705c-0.785,0-1.424,0.765-1.424,1.705h-1.039c0-1.512,1.105-2.742,2.463-2.742s2.463,1.23,2.463,2.742H16.387z"})
    );

    wp.blocks.registerBlockType('plugin-name/gutenberg-block', {
        title: 'CustomBlockName',
        icon: iconSvg,
        category: 'widgets',

        edit: (props) => {
            // @TODO: we need a unique ID for each block!
            this.myId = props.attributes.itemId || Math.floor(Math.random() * 8388607); /// Medium int max value is 8388607;

            props.setAttributes(
                {
                    itemId: myId
                }
            );

            return wp.element.createElement(
                'div',
                {},
                [
                    wp.element.createElement(
                        'div',
                        {},
                        [
                            wp.element.createElement(
                                'img',
                                {
                                    src: PluginNameGutenbergBlock.preview_image
                                }
                            )
                        ]
                    )
                ]
            );
        },

        save: (props) => {
            let dataId = props.attributes.itemId;

            return wp.element.createElement(
                'div',
                {},
                [
                    wp.element.createElement(
                        'div',
                        {
                            class: 'plugin-name-outer'
                        },
                        [
                            wp.element.createElement(
                                'div',
                                {
                                    'class': 'plugin-name-container-async gutenberg-block',
                                    'data-id': dataId,
                                    'data-type': PluginNameGutenbergBlock.item_type
                                },
                                wp.element.createElement(
                                    'div',
                                    {
                                        'class': 'plugin-name-' + PluginNameGutenbergBlock.use_template
                                    },         {},
                                    [
                                        wp.element.createElement(
                                            'img',
                                            {
                                                src: PluginNameGutenbergBlock.loader_url
                                            }
                                        )
                                    ]
                                )
                            )
                        ]
                    )
                ]
            );
        }
    });

}());

Upvotes: 3

Views: 2240

Answers (1)

DanieleAlessandra
DanieleAlessandra

Reputation: 1555

I understood my error, so I post this answer hoping to help other people.

When I create a new block I first generate a random value for attribute data-id:

/// Inside edit function
this.myId = props.attributes.itemId || Math.floor(Math.random() * 8388607); /// Medium int max value is 8388607;

Then I set this value inside the shared props object:

/// Inside edit function
props.setAttributes(
    {
        itemId: myId
    }
);

Then when I save the block I just created the script find the generated value:

/// Inside save function
let dataId = props.attributes.itemId;

So the block creation works well, but when I open an existing post my script wasn't able to find saved value, so the value of dataId inside the save function was undefined and the attribute data-id was missing. This is the difference between saved block and generated block.

The missing part was the attributes block which read values from saved code and make them available inside edit and save function.

Here is my solution:

wp.blocks.registerBlockType('plugin-name/gutenberg-block', {
    title: 'CustomBlockName',
    icon: iconSvg,
    category: 'widgets',
    attributes: {                                         /// <--- this block was missing
        myId: {                                           /// <--- this is the name of the property
            type: 'string',                               /// <--- this is the type
            source: 'attribute',                          /// <--- this is where is located the value I want
            default: Math.floor(Math.random() * 8388607), /// <--- this is a default value for new blocks
            selector: 'div.gutenberg-block',              /// <--- this is a selector for an element in saved block
            attribute: 'data-id'                          /// <--- this is the name of the attribute that contains desired value
        },
    },
    edit: (props) => {
        let dataId = props.attributes.myId; /// <--- this is always defined as the value of data-id attribute or as random number (as string)
        ...
    },
    save: (props) => {
        let dataId = props.attributes.myId; /// <--- this is always defined as the value of data-id attribute or as random number (as string)
        ...
    }
});

Upvotes: 4

Related Questions