html-to-docx icon indicating copy to clipboard operation
html-to-docx copied to clipboard

Unhandled Rejection (TypeError): Cannot call a class as a function error

Open SensiateLeo opened this issue 4 years ago • 37 comments

Hello,

I'm using the html-to-docx lib to generate docx documents in one one my React projects and recently I am getting the following error when trying to use the HTMLtoDocx() method:

image

Apparently it starts on the 'html-to-docx.js:171' file. Any idea of why this is happening?

SensiateLeo avatar Sep 16 '21 19:09 SensiateLeo

Could you please post other details and the code you used?

privateOmega avatar Sep 17 '21 12:09 privateOmega

Sure. I use the lib to generate a docx document of one of my React components, so I added a button which triggers the following function when clicked:

const generateDocx = async (my variables) => {
  const html = ReactDOMServer.renderToStaticMarkup(<MyComponent
    componentProps
  />);
  const converted = await HTMLtoDOCX(html, null, {
    font: 'Roboto',
    margins: {
      top: '24px',
      right: '24px',
      bottom: '24px',
      left: '24px',
      header: 720,
      footer: 720,
      gutter: 0,
    },
    footer: true,
    pageNumber: true,
  });

  saveAs(converted, 'myDocument.docx');
};

It was working fine a few days ago, but now the app has started crashing. I don't know if it could be a version issue or something else.

SensiateLeo avatar Sep 17 '21 15:09 SensiateLeo

@SensiateLeo Any chance you added a new element to the page or the html output of renderToStaticMarkup changed significantly? Also which version of html-to-docx do you use ?

privateOmega avatar Sep 20 '21 19:09 privateOmega

@privateOmega unfortunately no. The page is the same as 1 month before. But recently I updated the project packages and some of the libraries had their version upgraded... could this be a problem? I was using the 1.2.2 version, but I also tried 1.2.3 and the problem persisted.

SensiateLeo avatar Sep 21 '21 14:09 SensiateLeo

@SensiateLeo Yes I guess, but cant say anything for sure, Could you please post the markup string here?

privateOmega avatar Sep 22 '21 17:09 privateOmega

@SensiateLeo @zees98 I think its possibly an issue with the import because of the loader you are using, could you please console.log(HTMLtoDOCX), I think instead of a function, its getting loaded as a class for some reason.

privateOmega avatar Sep 23 '21 20:09 privateOmega

Try out the following syntaxes

import name from "module-name";
import * as name from "module-name";
import { default as name } from "module-name";

One of it should work I guess.

privateOmega avatar Sep 23 '21 20:09 privateOmega

@privateOmega First of all, I really appreciate all the help. Secondly, I did as you suggested with the import statements. But no luck. I'll list down my finding with each method below.

import HTMLtoDOCX from 'html-to-docx'; import { default as HTMLtoDOCX} from "html-to-docx";

these 2 methods yield the same console.log result.

console.log results:

ƒ (_x, _x2) {
  return _ref14.apply(this, arguments);
}

import * as HTMLtoDOCX from 'html-to-docx'; This yields a different error which is kind of similar to the OP's error.

Unhandled Rejection (TypeError): html_to_docx__WEBPACK_IMPORTED_MODULE_11__ is not a function

Console.log results: error

zees98 avatar Sep 24 '21 08:09 zees98

@zees98 Can we try import { HTMLtoDOCX } from 'html-to-docx'; as well? It's a fluke attempt, but I am out of ideas.

privateOmega avatar Sep 24 '21 08:09 privateOmega

@zees98 @SensiateLeo are you guys on webpack 5?

privateOmega avatar Sep 24 '21 08:09 privateOmega

@zees98 Can we try import { HTMLtoDOCX } from 'html-to-docx'; as well? It's a fluke attempt, but I am out of ideas.

image

zees98 avatar Sep 24 '21 08:09 zees98

@zees98 @SensiateLeo are you guys on webpack 5?

i executed npx webpack --version in my project and got this:

webpack 4.44.2
webpack-cli 4.8.0
webpack-dev-server 3.11.1

zees98 avatar Sep 24 '21 08:09 zees98

Update: I upgraded Webpack.

webpack 5.53.0   
webpack-cli 4.8.0

But the issue persists.

zees98 avatar Sep 24 '21 09:09 zees98

@privateOmega First of all, I really appreciate all the help until the moment.

As @zees98, I tried all the steps that you suggested but the issue still persists

SensiateLeo avatar Sep 24 '21 14:09 SensiateLeo

I'm also getting the same errors that @zees98 commented before

SensiateLeo avatar Sep 24 '21 14:09 SensiateLeo

@zees98 @SensiateLeo could one of you make a sandbox repo for me also to reproduce this issue?

privateOmega avatar Sep 24 '21 14:09 privateOmega

@zees98 @SensiateLeo could one of you make a sandbox repo for me also to reproduce this issue?

Sure, I'm on it.

zees98 avatar Sep 24 '21 15:09 zees98

@privateOmega @SensiateLeo I wanted to report that the package is indeed working. I made the sandbox project (adding to GitHub in a bit). But what I find mysterious is that the code was a copy and paste.

Attaching GIF below demo

zees98 avatar Sep 24 '21 15:09 zees98

@privateOmega @SensiateLeo Hello, again guys!

I have got the package to work for me!

I just removed the conversion code from my front end and added it as an API route to my project's backend. Now it works fine.

Here is the server-side route code

app.post('/files/generate/', async (req, res) => {
    var { html } = req.body;
    console.log(req.body)
    if (html !== undefined) {
      var html = `<!DOCTYPE html><html lang="en">
                      <head>
                        <meta charset="UTF-8" />
                        <title>Document</title>
                      </head>
                    <body>
                     ${html} 
                    </body>
                  </html>`;
      const fileBuffer = await HTMLtoDOCX(html, null, {
        table: { row: { cantSplit: true } },
        footer: true,
        pageNumber: true,
      });
      console.log(fileBuffer);
      var path = `${__dirname}/files/document_${Date.now()}.docx`;
      fs.writeFile(path, fileBuffer, (err) => {
        if (err) {
          console.log(err)
        }
        else {
          res.setHeader("Content-Type", "application/msword");
          fs.createReadStream(path).pipe(res);
        }
      });
    }
    else
      return res.status(400).json({ error: "HTML cannot be null" })
  });

This may not be the perfect solution for some cases but I believe my project was the problem here and this workaround does not affect my original use case at all, other than the fact that I primarily wanted to be able to generate files at client side.

zees98 avatar Sep 26 '21 13:09 zees98

@zees98 I'm so happy that you could make it work by running it in the backend, but then again I wish it was working you for the frontend setup as well.

I strongly feel its an import problem due to some loader issue, which is something similar to what I was facing when I was trying to make it work on browsers, for setups without frameworks like react.

If one of you has some experience with loaders and could help sort this out, that would be amazing, but kudos nevertheless.

privateOmega avatar Sep 27 '21 17:09 privateOmega

@privateOmega Thank you so much! I have been working with Javascript for a total of 4-5 months now. Once I study loaders in JS, I'll be more than happy to help out! Cheers!

zees98 avatar Sep 29 '21 06:09 zees98

I did a blanket upgrade modules and it worked

 "color-name": "^1.1.4",
"escape-html": "^1.0.3",
"html-to-vdom": "^0.7.0",
"image-size": "^1.0.2",
"jszip": "^3.10.0",
"nanoid": "^4.0.0",
"virtual-dom": "^2.1.1",
"xmlbuilder2": "^3.0.2"

shareefalis avatar Jul 28 '22 23:07 shareefalis

Hello! Unfortunately the project I am working on is running into the same issue with production build. We are using react-scripts, checking the webpack version react-scripts is running webpack 4.44.2. I'm wondering @shareefalis when you say you blanket upgraded the modules, where did you do this?

Oracard avatar Aug 04 '22 08:08 Oracard

in package.json, in the dependency section of the npm module, this is what i upgraded in the snippet to get the module working.. I believe there is a loader fix in one of the module which fixed this issue

shareefalis avatar Aug 04 '22 14:08 shareefalis

I am jumping in, facing the same issue with Webpack 4.

From the suggestion from @privateOmega about the module import, I tried this PR but webpack then can't find this library, see my comment in the PR.

zedtux avatar Nov 16 '22 19:11 zedtux

I finally figured it out by looking at which library was using this @oozcitak/infra package raising the error and found that only xmlbuilder2 is.

I found this issue from the library's repo by searching the error message in the issues. In that issue, the library author fixed the error and asked to use xmlbuilder2 version 2.1.4. html-to-docx uses the version 2.1.2 so I tried upgrading it and it works !

See my PR #168.

zedtux avatar Nov 16 '22 20:11 zedtux

Released v1.6.3 which should fix this issue. Sorry guys it took forever. Also whoever followed blanket update of packages, I am guessing you guys werent using images, because that should be broken(generate bad .docx file) if you did that I am guessing.

privateOmega avatar Nov 17 '22 19:11 privateOmega

@privateOmega installation of 1.6.3 fails on my machine :

[4/4] Building fresh packages...
error /application/node_modules/html-to-docx: Command failed.
Exit code: 127
Command: npx npm-force-resolutions
Arguments: 
Directory: /application/node_modules/html-to-docx
Output:
/bin/sh: npx: not found

1.6.2 wasn't failing.

zedtux avatar Nov 17 '22 19:11 zedtux

@zedtux Yes I am forcing the deps of xmlbuilder2 to be the ones that was basically the fix of 2.1.4 of xmlbuilder2. For you its failing probably because you are on older version of node and npm like npm < 7. I am guessing. Is it possible for you to upgrade npm version?

Also 1.6.2 doesnt contain the fix, only 1.6.3 does.

privateOmega avatar Nov 17 '22 20:11 privateOmega

@privateOmega I'm using Docker, and installing Node 14 (still old) using the Alpine Linux package manager (I just figured out that the npm and npx command are shipped by the Linux Alpine package npm, while nodejs only ship node alone).

I just updated my Docker image in order to install and preserve the npm and npx commands so that now I do have the npx command but it crashes with :

error /application/node_modules/html-to-docx: Command failed.
Exit code: 1
Command: npx npm-force-resolutions
Arguments: 
Directory: /application/node_modules/html-to-docx
Output:
npm WARN exec The following package was not found and will be installed: npm-force-resolutions
Error: ENOENT: no such file or directory, open './package-lock.json'
    at Object.openSync (fs.js:498:3)
    at Object.fs [as readFileSync] (fs.js:394:35)
    at npm_force_resolutions$core$node_slurp (/home/zedtux/.npm/_npx/73b02210abc194ff/node_modules/npm-force-resolutions/out/npm_force_resolutions/core.cljs:15:20)
    at npm_force_resolutions$core$read_json (/home/zedtux/.npm/_npx/73b02210abc194ff/node_modules/npm-force-resolutions/out/npm_force_resolutions/core.cljs:22:23)
    at switch__2144__auto__ (/home/zedtux/.npm/_npx/73b02210abc194ff/node_modules/npm-force-resolutions/out/npm_force_resolutions/core.cljs:151:3)
    at /home/zedtux/.npm/_npx/73b02210abc194ff/node_modules/npm-force-resolutions/out/npm_force_resolutions/core.cljs:151:3
    at npm_force_resolutions$core$update_package_lock_$_state_machine__2145__auto____1 (/home/zedtux/.npm/_npx/73b02210abc194ff/node_modules/npm-force-resolutions/out/npm_force_resolutions/core.js:648:4)

A possible fix could be to use npx force-resolutions instead ?

zedtux avatar Nov 17 '22 20:11 zedtux