convertFromHTML("<p> </p>"); // returns null
I'll assume "returns null" is meant literally in which case updating to the most recent draft-js
version should fix the problem.
Here's my example
running
create-react-app
v1.5.2
draft-js
v0.10.5
console.log(convertFromHTML('<p> </p>'))

There is a "valid" object, but the contentBlocks
property is null
, which means we cannot create a valid ContentState
as you'll get the following:
TypeError: Cannot read property 'contentBlocks' of null
Any thoughts on why it might be happening?
Short Answer: The HTML node needs text.
In-Depth Answer:
All of the following code is adapted from the most recent version of draft-js
source at the time of this writing (commit 4c4465f). Some sections of methods are left out for brevity.
The method convertFromHTMLtoContentBlocks
is what's called by this module and it has a few main steps:
- process the html string
- create a DOM from the string
- produce blocks from the DOM
- Mapping the blocks to the
contentBlocks
object
1) Processing the string to a DOM
The html gets processed by a method getChunkForHTML
the output from which the contentBlocks
is created.
const convertFromHTMLtoContentBlocks = (
html: string,
DOMBuilder: Function = getSafeBodyFromHTML,
blockRenderMap?: DraftBlockRenderMap = DefaultDraftBlockRenderMap,
): ?{contentBlocks: ?Array<BlockNodeRecord>, entityMap: EntityMap} => {
const chunkData = getChunkForHTML( // processing our html string into chunkData
html,
DOMBuilder,
blockRenderMap,
DraftEntity,
);
// use the chunkData to create contentBlocks
const {chunk, entityMap} = chunkData;
const contentBlocks = convertChunkToContentBlocks(chunk);
return {
contentBlocks,
entityMap,
};
};
Inspecting getChunkForHTML
, we see that the white-space is trimmed to <p></p>
and passed to DOMBuilder
. The DOM created by DOMBuilder
is converted into blocks by genFragment
, prettied and returned as chunk
.
const getChunkForHTML = (
html: string,
DOMBuilder: Function,
blockRenderMap: DraftBlockRenderMap,
entityMap: EntityMap,
): ?{chunk: Chunk, entityMap: EntityMap} => {
html = html // the string is trimmed
.trim()
.replace(REGEX_CR, '')
.replace(REGEX_NBSP, SPACE)
.replace(REGEX_CARRIAGE, '')
.replace(REGEX_ZWS, '');
const safeBody = DOMBuilder(html); // create DOM from trimmed html
if (!safeBody) {
return null;
}
const fragment = genFragment(
entityMap,
safeBody, // use DOM to create blocks in genFragment
OrderedSet(),
'ul',
null,
workingBlocks,
-1,
blockRenderMap,
);
let chunk = fragment.chunk;
const newEntityMap = fragment.entityMap;
// rest of method
return {chunk, entityMap: newEntityMap};
};
2) Create DOM from string
If we inspect the DOMBuilder
method (alias for getSafeBodyFromHTML
) (source) in the debugger, we see that we get a DOM node with these properties:
innerHTML: "<p></p>"
innerText:""
3) Generating Blocks from the DOM
The output of DOMBuilder
is an argument to genFragment
as safeBody
. This method processes the DOM tree into blocks. Given that our DOM contains no text, the object returned from genFragment
has the property: text: ""
.

4)Mapping the blocks to contentBlocks
The last call in the convertFromHTMLtoContentBlocks
is
const contentBlocks = convertChunkToContentBlocks(chunk);
:
const convertChunkToContentBlocks = (chunk: Chunk): ?Array<BlockNodeRecord> => {
if (!chunk || !chunk.text || !Array.isArray(chunk.blocks)) {
return null;
}
// rest of method
}
clearly, at this point chunk.text
returns false
and thus contentBlocks
is null
.