Search code examples
javascriptjquerynode.jsjsdomdraftjs

span and strong tags are not working in jsdom


I am new to jsdom and I just want to convert html tags to json using draft js in node services. I got jsdom for conversion, so I worked on that so normal tags are working fine but some tags are not working. Here is my code.

    const { JSDOM } = jsdom;
    const { window } = new JSDOM();
    const { document } = (new JSDOM(`<!DOCTYPE html>`)).window;
    global.document = document;
    global.navigator = window.navigator
    global.HTMLElement = window.HTMLElement
    const djs = require('draft-js')
    const html = '<p>Hey this <span>editor</span> rocks 😀</p>';
    const json=djs.convertToRaw(djs.ContentState.createFromBlockArray(djs.convertFromHTML(html)))
    console.log("Hello",json);
    var jQuery = require('jquery')(window);

It is giving me error

node:22923) UnhandledPromiseRejectionWarning: ReferenceError: Node is not defined
    at isElement (/home/ec2-user/environment/info-data-migration/node_modules/draft-js/lib/isElement.js:18:28)
    at isHTMLImageElement (/home/ec2-user/environment/info-data-migration/node_modules/draft-js/lib/isHTMLImageElement.js:20:10)
    at isValidImage (/home/ec2-user/environment/info-data-migration/node_modules/draft-js/lib/convertFromHTMLToContentBlocks.js:184:8)
    at ContentBlocksBuilder._toBlockConfigs (/home/ec2-user/environment/info-data-migration/node_modules/draft-js/lib/convertFromHTMLToContentBlocks.js:490:11)
    at ContentBlocksBuilder._toBlockConfigs (/home/ec2-user/environment/info-data-migration/node_modules/draft-js/lib/convertFromHTMLToContentBlocks.js:432:52)
    at ContentBlocksBuilder.addDOMNode (/home/ec2-user/environment/info-data-migration/node_modules/draft-js/lib/convertFromHTMLToContentBlocks.js:333:82)
    at Object.convertFromHTMLToContentBlocks [as convertFromHTML] (/home/ec2-user/environment/info-data-migration/node_modules/draft-js/lib/convertFromHTMLToContentBlocks.js:791:63)
    at Object.rawFromHTML (/home/ec2-user/environment/info-data-migration/controller/jsontoHTMLConverter.js:170:24)
    at Object.getCandidateTableData (/home/ec2-user/environment/info-data-migration/controller/candidate_fullfile.js:31:119)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:22923) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:22923) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

fun fact code is working without span tags.

const { JSDOM } = jsdom;
    const { window } = new JSDOM();
    const { document } = (new JSDOM(`<!DOCTYPE html>`)).window;
    global.document = document;
    global.navigator = window.navigator
    global.HTMLElement = window.HTMLElement
    const djs = require('draft-js')
    const html = '<p>Hey this rocks 😀</p>';
    const json=djs.convertToRaw(djs.ContentState.createFromBlockArray(djs.convertFromHTML(html)))
    console.log("Hello",json);
    var jQuery = require('jquery')(window);

I need to convert html data to json.


Solution

  • Since you're adding browser objects to node's global, you also need to add the Node object like so:

    // [...]
    global.HTMLElement = window.HTMLElement
    global.Node = window.Node // <== Add this
    // [...]
    

    This is because the nested <span> tag creates text nodes inside the <p> tag and Draft.js is parsing these.

    I don't know the context of your code but if you simply have an HTML string that you'd like to convert to JSON/JS objects, it might be easier to use something like xml2js instead:

    const util = require('util');
    const parseString = util.promisify(require('xml2js').parseString); // `promisify` makes it possible to use `async/await`
    
    (async function(){
        const obj = await parseString('<p>Hey this <span>editor</span> rocks 😀</p>');
        console.log(obj); // { p: { _: 'Hey this  rocks 😀', span: [ 'editor' ] } }
    }());