Do you want to request a feature or report a bug?
Bug report
What is the current behavior?
/*
* > editorState.getCurrentContent().getEntity(entityKey).getData()
* <- {name: 'John', id: '3'}
*/
const contentState = editorState.getCurrentContent()
const newContentState = contentState.mergeEntityData(entityKey, {name: 'Pete'})
/*
* > editorState.getCurrentContent().getEntity(entityKey).getData()
* Should still return {name: 'John', id: '3'}, but actually returns {name: 'Pete', id: '3'}
*/
This being the case, we cannot push the new contentState onto editorState because
editorState.getCurrentContent() === contentState
returns true and EditorState.push() exits with the base case.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. You can use this jsfiddle to get started: https://jsfiddle.net/stopachka/m6z0xn4r/.
Just try it out in the console as above.
What is the expected behavior?
These model objects should be immutable, no? Regardless, we should be able to push a contentState with updated entity data.
Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js?
master branch, Google Chrome, macOS Sierra
I could be wrong here...but I think the plan is to entirely move Entities into the ContentState (which in turn will fix what you've described). Currently though, entities are stored in its own place, outside of the immutable EditorState. In the version on master (often referred to as v0.10), the ContentState has been updated to act as a bridge to the entities (rather than actually storing them), using the upcoming API. The reason for this is to give people a chance to update to the new API before any breaking changes.
Ah, that will be a welcome change. Do you have any suggestions for how to manage this situation for now? I do need to be able to push updates to editorState to my redux store even just to make the controlled <input /> I'm using to edit entity data accept input.
I ended up just accepting the mutation of editorState in this context. For anyone else with the same problem, I鈥檓 merging entity data as above, then skipping the editorState.push step and dispatching updateEditorState with the mutated object. Looking forward to 0.11.
Have same issue. And i think it is very stange behavior.
@cbothner can you explain how do you dispatch updateEditorState?
@iseeyou911 Sorry that I let this fall off the radar. I'm just calling my onChange function the same as I would if the user typed a letter.
onChange(editorState) {
this.setState({ editorState })
}
onChangeCitationData(e) {
const contentState = editorState.getCurrentContent()
/*let newContentState = */contentState.mergeEntityData(openedCitation.key, {value: e.currentTarget.value})
// When eventually the Entity API is rejiggered so entities are inside of
// ContentState, then we鈥檒l have to push newcontentState. For now,
// mergeEntityData is mutating editorState, so we just dispatch the object
// itself.
//
// onChange(EditorState.push(editorState, newContentState, 'apply-entity'))
onChange(editorState)
}
// When eventually the Entity API is rejiggered so entities are inside of
// ContentState, then we鈥檒l have to push newcontentState. For now,
// mergeEntityData is mutating editorState, so we just dispatch the object
// itself.
@cbothner would this be necessary now?
I'm trying to modify an entity but the editor doesn't get updated:
const { path, filename } = data;
contentState = editorState.getCurrentContent();
const updatedContentState = contentState.replaceEntityData(entityKey, {
src: path,
alt: filename
});
// create a new EditorState with the updated entity
editorStateWithEntity = EditorState.set(editorState, {
currentContent: updatedContentState
});
this.onChange(editorStateWithEntity);
As of v0.10 it is still as I wrote. You can see here that ContentState is delegating to the old internals of DraftEntity. I've got it working _without_ ever creating a new EditorState. As I have it working, your example would be
const { path, filename } = data;
contentState = editorState.getCurrentContent();
contentState.replaceEntityData(entityKey, { src: path, alt: filename });
this.onChange(editorState);
@krishnagopinath many thanks!
Most helpful comment
As of v0.10 it is still as I wrote. You can see here that
ContentStateis delegating to the old internals ofDraftEntity. I've got it working _without_ ever creating a newEditorState. As I have it working, your example would be