Search code examples
wordpresswordpress-gutenberg

Gutenberg attributes not being saved or retrieved properly?


In a horrific demonstration of jumping in at the deep end, I'm experiencing my first bit of React development by build a more than simple Gutenberg block. Foolish!

Anyway, the block I'm making is pulling in the content from a custom post type, selected via the post ID from a SelectControlbox in the InspectorControls.

<SelectControl 
   onChange={ onSelectPost } 
   value={ attributes.selectedpost } 
   label={ __( 'Select a Post' ) } 
   options={ options } 
/>

This is working fine and rendering ok!

The selected post ID is saved as an attribute when the value is changed:

const onSelectPost = ( post ) => {
    setAttributes( {
        selectedpost: post,
    } );
};

later on, I then check to see if this is set, and if so, retrieve the content and populate an innerblocks template with some content.

This displays all fine in the first edit screen and on the final result, but when you go back to edit the content, it has lost the selectedpost attribute!

Here is the attribute def:

attributes: {
    selectedpost: {
        type: 'number',
        default: 0, 
    },

and here is the save:

save: function( props ) {       
    const blockProps = useBlockProps.save();
    const { attributes } = props;
    
    return (
        <div { ...blockProps } key="sandcexercise">
            <InnerBlocks.Content /> 
        </div>
    );  
},

As I haven't specified a source for the attribute, I'm expecting it to be saved as a comment and reloaded from there.

If I convert the attribute to being outputted into a p tag, it all works fine!

The converted attribute:

attributes: {
        selectedpost: {
            type: 'text',
            source: 'text',
            selector: 'p.selectedpost',     
        },

and adding this line to the edit and save functions:

<p className="selectedpost">{ attributes.selectedpost }</p>

The weird thing is, I've a bunch of other attributes which are being picked up from the comments correctly, just not my selectpost number!

Any ideas what I might be doing wrong? I know virtually no React at all, and the last time I really did anything in anger with Javascript was in 2002 making things move around screen so I'm really stuffed with debugging!


Solution

  • Overall, the code sample you provided and your explaination show you're on the right path with creating a Gutenberg block with ReactJS and handling attributes, well done/don't give up!

    As your selectedpost attribute is a number, ensure value saved by setAttributes() is also be number by using parseInt(), eg:

    const onSelectPost = ( post ) => {
        setAttributes( {
            selectedpost: parseInt(post)
        });
    };
    

    On reload, by keeping the value the correct type (number), the saved value then matches one of the 'options' (post ids) in your <SelectControl>. This also explains why it works when you use <p> as the value is a stored as a string within <p>..</p>.

    Tip: Using the browser console to debug can help you track down issues quickly; React error messages in the console can be useful in finding/resolving issues and potentially reduce frustration...