Gutenberg: Is there any onAdd event for blocks?

Created on 7 Aug 2018  路  4Comments  路  Source: WordPress/gutenberg

Like on the title, I am willing to be able to add a callback while my custom block is added on editor. Like I am creating some countdown which is initializing by a jquery function call by taking data from html data attributes.

Now I am willing the function to be run while I have added a new countdown element on my editor (by taking it's default value).

[Type] Help Request

Most helpful comment

There are no events in Gutenberg. The idea is that there are selectors that can give you at anytime the data in Gutenberg (for example the list of blocks in the post) and there's a unique event emitter you can use to track whether the state (entire state) change or not. For example you can do:

const getBlockList = () => wp.data.select( 'core/editor' ).getBlocks();
let blockList = getBlockList();
wp.data.subscribe(() => {
  const newBlockList = getBlockList();
  const blockListChanged = newBlockList !== blockList;
  blockList = newBlockList;
  if ( blockListChanged ) {
    // You can trigger here any behavior when the block list in the post changes.
  }
});

You can check the handbook for all the available selectors you can use this way https://wordpress.org/gutenberg/handbook/data/

it's also good to take a look at the documentation of the Data Module.

I hope this helps. Thanks

All 4 comments

There are no events in Gutenberg. The idea is that there are selectors that can give you at anytime the data in Gutenberg (for example the list of blocks in the post) and there's a unique event emitter you can use to track whether the state (entire state) change or not. For example you can do:

const getBlockList = () => wp.data.select( 'core/editor' ).getBlocks();
let blockList = getBlockList();
wp.data.subscribe(() => {
  const newBlockList = getBlockList();
  const blockListChanged = newBlockList !== blockList;
  blockList = newBlockList;
  if ( blockListChanged ) {
    // You can trigger here any behavior when the block list in the post changes.
  }
});

You can check the handbook for all the available selectors you can use this way https://wordpress.org/gutenberg/handbook/data/

it's also good to take a look at the documentation of the Data Module.

I hope this helps. Thanks

I have no idea how to use this on a targeted block. Here below is my code. I am willing to run the function countdown while this block is added on editor. This is currently running on onChange only

(function (wpBlocks, wpEditor, wpComponents, wpElement) {
    const {InspectorControls, RichText, MediaUpload, PlainText, ColorPalette} = wpEditor;
    const {registerBlockType} = wpBlocks;
    const {Button, PanelBody, PanelColor, FontSizePicker, DateTimePicker, SelectControl} = wpComponents;
    const {Fragment,Component} = wpElement;
    class CountDown extends Component {
        constructor() {
            super(...arguments);
            countdown();
        }
        render(){
            const { attributes, className, setAttributes, isSelected } = this.props;
            const {
                dateTime
            } = attributes;
            return (
                <Fragment>
                    <InspectorControls>
                        <PanelBody title="Set Date & Time" initialOpen={true}>
                            <DateTimePicker
                                currentDate={dateTime}
                                onChange={(currentDate) => {
                                    setAttributes({dateTime: currentDate})
                                    countdown()
                                }}
                            ></DateTimePicker>
                        </PanelBody>
                    </InspectorControls>
                    <div className="countdown">
                        <div
                            className="ex-countdown"
                            data-time={dateTime}
                        ></div>
                    </div>
                    {isSelected && (
                        countdown()
                    )}
                </Fragment>
            );
        }
    }
    registerBlockType('ex/countdown', {
        title: 'Countdown',
        icon: 'screenoptions',
        category: 'common',
        attributes: {
            dateTime: {
                type: 'string',
                default: '2019/08/18 00:00:00'
            }
        },
        edit: CountDown,
        save({attributes}) {
            const {dateTime} = attributes;
            return (
                <div className="countdown">
                    <div className="ex-countdown" data-time={dateTime}></div>
                </div>
            )
        }
    });
})(wp.blocks, wp.editor, wp.components, wp.element);

your block name is called ex/countdown so instead of comparing the entire list of blocks like I did above, you can filter the list of blocks by their name and count how many blocks with the name ex/countdown exist and if this count changes, it means one of your blocks have been added or removed.

your block name is called ex/countdown so instead of comparing the entire list of blocks like I did above, you can filter the list of blocks by their name and count how many blocks with the name ex/countdown exist and if this count changes, it means one of your blocks have been added or removed.

@youknowriad how can you filter the list of blocks by their name? I'm currently using forEach but I'm not sure this is the most performant way:

const getBlockList = () => wp.data.select( 'core/block-editor' ).getBlocks();

getBlockList().forEach( function( blockType ){
    console.log( blockType.name );
});
Was this page helpful?
0 / 5 - 0 ratings