Draft.js. How to get all entities data from the ContentState
Asked Answered
N

6

6

From official docs I know about 2 methods: get entity by its key and get last created entity. In my case, I also need a method to access all entities from current ContentState. Is there any method that could perform this? If not, is there a one that can provide all entities keys?

Nubbin answered 24/9, 2017 at 23:52 Comment(3)
why not keep a set of entities you created?Agog
Thanks for ur answer. I'll try this too. The problem is to setup automatically removing an entity from this set when user removes range with entityNubbin
editorState should fully represent the state of the editor. Maintaining a separate set of entities goes against the "single source of truth" principle.Zingale
D
13

const getEntities = (editorState, entityType = null) => {
    const content = editorState.getCurrentContent();
    const entities = [];
    content.getBlocksAsArray().forEach((block) => {
        let selectedEntity = null;
        block.findEntityRanges(
            (character) => {
                if (character.getEntity() !== null) {
                    const entity = content.getEntity(character.getEntity());
                    if (!entityType || (entityType && entity.getType() === entityType)) {
                        selectedEntity = {
                            entityKey: character.getEntity(),
                            blockKey: block.getKey(),
                            entity: content.getEntity(character.getEntity()),
                        };
                        return true;
                    }
                }
                return false;
            },
            (start, end) => {
                entities.push({...selectedEntity, start, end});
            });
    });
    return entities;
};
Deuteragonist answered 5/10, 2017 at 22:37 Comment(1)
That let selectedEntity is not the nicest piece of JS code ever, but it's as if the creators of Draft.js API wanted people to write horrible code...Zingale
S
5

How I get the all entities keys:

const contentState = editorState.getCurrentContent()
const entityKeys = Object.keys(convertToRaw(contentState).entityMap)

result:

[0, 1]

then you can call the getEntity(key) method to get the responding entity.

this is how convertToRaw(contentState) looks:

enter image description here

Sigismond answered 23/8, 2018 at 7:28 Comment(1)
Hey check my above comment.Assuasive
A
0

Bao, You will find it inside key called 'blocks'.

convertToRaw(contentState).blocks.map(el=>el.text)
It will give you an array of raw text.
Assuasive answered 27/11, 2018 at 13:53 Comment(1)
hey SBimochan, in fact, blocks are different with entities, you may have 5 blocks but only 2 entities. the asker wants to get keys of entities, not blocks, even blocks have no key because blocks are array while entities are map.Sigismond
S
0

Unfortunatelly your suggested way using convertToRaw doesnt work because it reindexes all keys to ["0", .., "n"], but the real keys differ when you act with the editor. New ones > n will be added and unused will be omitted.

Surgy answered 30/8, 2019 at 13:37 Comment(1)
and how we'd obtain that? the real key I mean?Shadowy
B
0

const rawState = convertToRaw(contentState) const { entityMap } = rawState;

This entityMap will have list of all entities. But this is an expensive conversion. Because, it will convert whole thing to raw. A better way is loop through blocks and check for entity.

Benjie answered 15/10, 2019 at 5:17 Comment(0)
W
0

You'll have to look at every character:

    const { editorState } = this.state; // assumes you store `editorState` on `state`
    const contentState = editorState.getCurrentContent();

    let entities = [];
    contentState.getBlockMap().forEach(block => { // could also use .map() instead
      block.findEntityRanges(character => {
        const charEntity = character.getEntity();
        if (charEntity) { // could be `null`
          const contentEntity = contentState.getEntity(charEntity);
          entities.push(contentEntity);
        }
      });
    });

Then you could access it via:

    entities.forEach((entity, i) => {
      if (entity.get('type') === 'ANNOTATION') {
        const data = entity.get('data');
        // do something
      }
    })
Whosoever answered 18/10, 2019 at 1:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.