htmlToDocx? No! docxToHtml! How about both?
Published: 2022-07-26 14:05:00

Wait a minute... didn't you already do this sorta play on article title? Why yes.

Yes I did.

![OOps I did it again](https://th.bing.com/th/id/R.b077fb9edbf0105cedfccfe16602dd19?rik=RwFIzAgwzsK8jQ&riu=http%3a%2f%2f25.media.tumblr.com%2ftumblr_mco2wr7vTH1qgiq62o1_500.gif&ehk=6Yb6TLv4MvDMU1%2f9pu0FGW8pyTWQ4wp28cNDx9ooSl0%3d&risl=&pid=ImgRaw&r=0)

- [Live Demo](https://haxapi.vercel.app/?path=/story/micro-frontends-core-services--docx-to-html)
- [Source for microservice](https://github.com/elmsln/lrnwebcomponents/blob/master/api/services/media/format/docxToHtml.js)
- [Source for demo](https://github.com/elmsln/lrnwebcomponents/blob/master/elements/micro-frontend-registry/demo/docx-example.js#L68-L89)

This will cover a slightly more complex aspect of a micro frontend (at least on one side of that transaction) which is taking a FormData object to allow for uploading files, then using a npm package called [busboy](https://www.npmjs.com/package/busboy) which is used for "parsing incoming HTML form data" as well as [concat-stream](https://www.npmjs.com/package/concat-stream) for file upload via that form data `POST`.

This end point / use case involves:
- our user already having content in a format they are used to working with `.docx` files
- asking them to upload that file via HTML form
- `POST`ing to our micro
- Loading the file as a stream / `tmp` as not to store it (because it's a Lambda it has no ability to save)
- Taking this streamed content and converting to HTML
- sending back to the user

The process of converting HTML into a `.docx` is very straight forward and not too dissimilar from the previous htmlToMd example shown, so this post will focus on The Hard Problem™.

# new FormData
Did you know that you can programatically create and populate [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) as if it was accepted via an `input` tag? I didn't before writing this, but it makes perfect sense. All the HTML tags are (typically) just hitting JS APIs that we can access or at least have some parallel.

Here's the source leveraged in the public demo that's using a `new FormData` in order to render an `input` tag, handle file selection, issue the `POST` to our micro and render the responding HTML.

```js
  // docx to html
  docxToHtmlRender() {
    return html`
    <label>Upload Docx file to get HTML</label>
    <input type="file" id="upload" @change="${this.docxToHtmlUpload}" />
    <textarea id="response" rows="10" cols="50"></textarea>
    <h1>HTML that was in the file upload</h1>
    <div id="here"></div>
    `;
  }

  docxToHtmlUpload(event) {
    const files = event.target.files;
    const formData = new FormData();
    formData.append('upload', files[0]);
    MicroFrontendRegistry.call('@core/docxToHtml', formData, this.docxToHtmlResponse.bind(this));
  }

  docxToHtmlResponse(data) {
    console.log(data);
    this.shadowRoot.querySelector("#here").innerHTML = data.data.contents;
  }
```

# Video time
I'll dig into how the microservice is processing this file and returning the results as it's a bit more complicated than the previous micros.

{% embed https://youtu.be/antauPzce9A %}