I am trying to remove an atomic block from the draftjs editor with Modifier.removeRange. From what I can tell I am passing in all the right arguments, but the SelectionState for removal never gets removed. Here is my code. This also adds in a new atomic block. That part works fine, it's the removal aspect that returns the same contentState that i pass in.
upload_block_selection_state is the SelectionState object for removal. This object is obtained from editorState.getSelection() when it is rendered. It looks like this.
upload_block_selection_state = {
anchorKey: "c1kpk",
anchorOffset: 0,
focusKey: "c1kpk",
focusOffset: 0,
isBackward: false
}
and here is the function that should both remove the upload block and then add a new block. Adding works, removal does nothing.
function addAndRemoveMediaBlock(
entityURL,
entityType,
editorState,
setEditorState,
upload_block_selection_state
){
const contentBeforeAtomicBlock = editorState.getCurrentContent();
const contentAfterSelectionRemoval = Modifier.removeRange(
contentBeforeAtomicBlock,
upload_block_selection_state,
'forward'
);
const contentStateWithEntity = contentAfterSelectionRemoval.createEntity(entityType, 'IMMUTABLE', { src: entityURL });
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const editorStateAfterAtomicBlock = AtomicBlockUtils.insertAtomicBlock(
editorState,
entityKey,
entityKey
);
/*
below here relevant only to removing the empty block.
*/
const selectionStateBeforeAtomicBlock = editorState.getSelection();
const anchorKeyBeforeAtomicBlock = selectionStateBeforeAtomicBlock.getAnchorKey();
const contentAfterAtomicBlock = editorStateAfterAtomicBlock.getCurrentContent();
const blockSelectedBefore = contentAfterAtomicBlock.getBlockForKey(anchorKeyBeforeAtomicBlock);
const finalEditorState = (() => {
if(blockSelectedBefore.getLength() === 0){
const keyBefore = blockSelectedBefore.getKey();
const newBlockMap = contentAfterAtomicBlock.blockMap.delete(keyBefore);
const contentWithoutEmptyBlock = contentAfterAtomicBlock.set('blockMap', newBlockMap);
const editorStateWithoutEmptyBlock = EditorState.push(editorStateAfterAtomicBlock, contentWithoutEmptyBlock, 'remove-block');
return EditorState.forceSelection(editorStateWithoutEmptyBlock, contentWithoutEmptyBlock.getSelectionAfter());
}else{
return editorStateAfterAtomicBlock;
}
})();
setEditorState({
editorState: finalEditorState,
});
};
I figured it out.
const contentAfterSelectionRemoval = contentBeforeAtomicBlock.blockMap.delete(blockToRemoveKey);
This seems like an anti-pattern within an Immutable state so I ended up approaching the problem from another angle and didn't actually use this working solution.