Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TS Error: Property 'attribs' does not exist on type 'DOMNode'. #199

Closed
bicstone opened this issue Dec 22, 2020 · 11 comments · Fixed by #296
Closed

TS Error: Property 'attribs' does not exist on type 'DOMNode'. #199

bicstone opened this issue Dec 22, 2020 · 11 comments · Fixed by #296
Labels
question Further information is requested

Comments

@bicstone
Copy link

bicstone commented Dec 22, 2020

Expected Behavior

When upgrade from version 0.14.3 to 1.0, TypeScript type errors occurs.

error TS2339: Property 'attribs' does not exist on type 'DOMNode'.
error TS2339: Property 'name' does not exist on type 'DOMNode'.
error TS2339: Property 'children' does not exist on type 'DOMNode'.
...etc

Actual Behavior

No error occurs.

Steps to Reproduce

Upgrade from version 0.14.3 to 1.0.

Reproducible Demo

0.14.3: https://codesandbox.io/s/mutable-surf-7r84v?file=/src/App.tsx
1.0: https://codesandbox.io/s/async-wildflower-p1wxl?file=/src/App.tsx

MEMO: 5568ed7#diff-7aa4473ede4abd9ec099e87fec67fd57afafaf39e05d493ab4533acc38547eb8

@remarkablemark
Copy link
Owner

remarkablemark commented Dec 22, 2020

Thanks for opening this issue!

You'll need to do an instanceof check of domhandler's Element:

import { Element } from 'domhandler/lib/node';

const options: HTMLReactParserOptions = {
  replace: (domNode) => {
    if (
      domNode instanceof Element &&
      domNode.attribs &&
      domNode.name === 'main'
    ) {
      const props = attributesToProps(domNode.attribs);
      return <div {...props} />;
    }
  },
};

See https://codesandbox.io/s/html-react-parser-199-ehdss

Let me know if you think exporting Element from html-react-parser and/or updating the README.md would help.

@remarkablemark remarkablemark added the question Further information is requested label Dec 22, 2020
@bicstone
Copy link
Author

Now I understand.
Thank you for your explanation!

@kevinpfox
Copy link

If you ended up here and tried the recommended solution and it still didn't work and you aren't interested in processing "Text" nodes and only care about processing "Tag" nodes, you can try the following...

import { isTag } from 'domhandler/lib/node';

replace: (domNode) => {
  if (isTag(domNode)) {
    const { attribs, children, name } = domNode;
  }

I don't know why the recommended solution did not work in our project. It looks logical. For our project domNode instanceof Element was always evaluating as false and execution refused to drop into the protected block.

@kevinpfox
Copy link

kevinpfox commented Jun 22, 2021

@remarkablemark, thank you for making your great tool available! Would be great if isTag and Element from domhandler library were exposed via html-react-parser, so domhandler doesn't need to be added as a project dependency. I wonder if html-react-parser's domhandler version and our project's imported domhandler version will go far enough out of sync to introduce a breaking change, or require the same library to be in the bundle twice, far off in the distant future.

@remarkablemark
Copy link
Owner

@kevinpfox I'm open to exporting isTag (and maybe Element) from domhandler if a lot of people are experiencing pain with the current approach.

I'm open to a PR but I do want to make sure including this won't add to the bundle size too much.

We can continue discussion in #252 if it's similar.

@kevinpfox
Copy link

Thanks for mentioning other thread. I tried the following approach and it fixed the same problem without needing to import an additional project dependency. https://gist.github.com/natterstefan/3bc712eca6ff88781d687b7240a78cc1 I'm also working on a Next.js project.

@remarkablemark
Copy link
Owner

Nice! If this is helpful, would you be interested in opening a PR to document that approach in the README.md?

@peckyboy
Copy link

Thanks for opening this issue!

You'll need to do an instanceof check of domhandler's Element:

import { Element } from 'domhandler/lib/node';

const options: HTMLReactParserOptions = {
  replace: (domNode) => {
    if (
      domNode instanceof Element &&
      domNode.attribs &&
      domNode.name === 'main'
    ) {
      const props = attributesToProps(domNode.attribs);
      return <div {...props} />;
    }
  },
};

See https://codesandbox.io/s/html-react-parser-199-ehdss

Let me know if you think exporting Element from html-react-parser and/or updating the README.md would help.

Why is this so though? I think exporting Element from html-react-parser and/or updating the README.md would help greatly.
Thank you.

@remarkablemark
Copy link
Owner

#296 released in 1.4.0

@dbehmoaras
Copy link

dbehmoaras commented Nov 9, 2021

Thanks for opening this issue!

You'll need to do an instanceof check of domhandler's Element:

import { Element } from 'domhandler/lib/node';

const options: HTMLReactParserOptions = {
  replace: (domNode) => {
    if (
      domNode instanceof Element &&
      domNode.attribs &&
      domNode.name === 'main'
    ) {
      const props = attributesToProps(domNode.attribs);
      return <div {...props} />;
    }
  },
};

See https://codesandbox.io/s/html-react-parser-199-ehdss

Let me know if you think exporting Element from html-react-parser and/or updating the README.md would help.

I tried this solution, but it does not work. The instanceof check returns false on every run. Unfortunately due to factors out of my control, we are unable to update to 1.4 (at least not yet). Do you have any other ideas? I would greatly appreciate your thoughts. Thanks!

***UPDATE:
I ended up solving this issue by doing the following instead of the instanceof check. I'm not entirely sure if this is the best approach but I think it should help in the meantime until we are able to update

import { Element } from 'domhandler/lib/node'
//... other logic
const options: HTMLReactParserOptions = {
  replace: (domNode) => {
    const domElement: Element = domNode as Element;
    //... logic that uses the domElement
  }
}

@mattsputnikdigital
Copy link

import { Element } from "html-react-parser";

Rather than from 'domhandler/lib/node' worked for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants