Don’t use getBlocks() to get the current post content
Published: – Leave a comment Last update:
When working with the whole content of the block editor, I noticed something odd: the getBlocks() selector does not necessarily return the current content of the editor. Let’s check why and how to correct it.
Initial, straight forward idea
My initial idea was to to get the whole content of the editor via this:
import { select } from '@wordpress/data';
const editorStore = select( 'core/block-editor' );
const blocks = editorStore.getBlocks();
Code language: JavaScript (javascript)
It was straight forward and according to the Block Editor Handbook, this was the content I wanted:
Returns all block objects for the current post being edited as an array in the order they appear in the post. Note that this will exclude child blocks of nested inner block controllers.
Block Editor Handbook
Old data
While I got a list of blocks, which look fine, I noticed something odd: Any changes I made to the blocks after initial load was not part of this data. That means, that the getBlocks selector only returns the blocks with their content while initializing the block editor. Or for blocks added afterwards: their initial content. Any change you make afterwards is not part of it.
Get most recent post content
It took me a while to find the correct selector in getEditorPostContent. This returns the post content with all the changes made since loading it, but as string. So in order to work with the block objects as they’re returned by getBlocks, we need to parse them to blocks, which is available as function in @wordpress/blocks. Thus, the correct code looks like this:
import { parse } from '@wordpress/blocks';
import { select } from '@wordpress/data';
const editorStore = select( 'core/editor' );
const blocks = parse( editorStore.getEditedPostContent() );
Code language: JavaScript (javascript)
Conclusion
As always, the block editor’s documentation is not always as helpful as it could be. And having no information about when the data you receive is set, doesn’t make it easier. Without checking the returned data in detail, there would be no possibility for me to recognize that the data from getBlocks do not include the latest changes. Having a solution with parsing getEditedPostContent at least doesn’t feel like a weird workaround.
Likes
Reposts