0

While trying to get the h3 heading text value using react-markdown, react web app throws following error in console. Could someone please advise, how can I get the h3 text value here ?

Uncaught TypeError: reactMarkdown.props.children.filter is not a function at getHeadingText (blogItem.js:86:1) at onClick (blogItem.js:99:1) at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)

function getHeadingText(markdownString) {
  if (!markdownString) {
    return null;
  }
  const reactMarkdown = <ReactMarkdown children={markdownString} remarkPlugins={[remarkGfm]} />
  console.log("Here::"+ reactMarkdown); // Debug output
  const h3Headings = reactMarkdown.props.children.filter(child => child.type === 'h3');
  const headingTexts = h3Headings.map(heading => heading.props.children);
  return headingTexts[0];
}
 
const Columns = () =>
<div className='blogItems'>
  <div className='row'>
   <div className='blogArea'>
   {!results.length && (<div className="noSearchData"><Wave text="Sorry, we couldn't find any results..!" /></div>)}
   { 
    results?.slice(0, loadBlogs).map (({id, blogdetails, views, createdAt }) => (
    <a key={id}
    onClick={
      () =>
        navigate(`/blogDetails/${getHeadingText(blogdetails)}`, {
          state: { id, blogdetails, views, createdAt}
        })
      } 
    >
      <div className='dataArea' onClick={() => getClickCount(id)} >
        <ReactMarkdown  children={blogdetails} className='dataDate renderElipsis tags readmoreLink views' remarkPlugins={[remarkGfm]}> 
        </ReactMarkdown>
        <div className='blogDate'>
            {moment(createdAt).format('DD-MMM-YYYY')}
             <a className='moreLink'>
              Read more →
             </a>
          </div>
      </div>
    </a>
   ))}
   </div>
  </div>
</div>  

Please note: react-markdown string looks like as below:

"![](https://picsum.photos/200)
##### 27 Feb 2023
###### unix
### Unix commands relevant
Best heading added here.Print the whole text here."

enter image description here

enter image description here

soccerway
  • 10,371
  • 19
  • 67
  • 132

1 Answers1

2

Probably blogdetails is undefined at the point you try reactMarkdown.props.children.filter, since children is set by attribute children={blogdetails} and I guess the blogdetails are fetched asynchronously somewhere.

The code is really quite complicated, and it's not all shown above, but if that's the case then you want to conditionally render

<ReactMarkdown children={blogdetails || []} ...></ReactMarkdown>

or

<div className='dataArea' onClick={() => getClickCount(id)} >
  {blogdetails ? <ReactMarkdown children={blogdetails || []} ...></ReactMarkdown> : null}

You will also need to make sure the component re-renders when blogdetails are fetched using something like a useEffect().

Mike G
  • 179
  • 9
  • Thank you for the reply. I could see the markdownString has the string data available. I have atatched the screenshot in my question – soccerway May 02 '23 at 22:20
  • Any suggestion, i have tried the above way suggested..but no luck yet – soccerway May 03 '23 at 00:16
  • Are you confirming blogs are async? If so, they can be undefined initially (which causes the error) but later has data (when you take the screen shot). The error just says filter is not a function, which could also mean it's initially not an array (if it was an array children.filter would work). It's hard to guess, even with the repo it would take an hour or so to track down. You need to console.log the bloglist before it's passed into ` – Mike G May 03 '23 at 02:06
  • Oh wait, it's the `markdownString` - that's a string, so you can't `.filter()` a string! – Mike G May 03 '23 at 02:09
  • What do the docs for ReackMarkdown say need to be passed into the children prop? Must be an array of some sort (array of strings?) Is it supposed to be ` – Mike G May 03 '23 at 02:11
  • So, the docs for Reactmarkdown say children ***is*** a string, but you have added the line causing the issue - `const h3Headings = reactMarkdown.props.children.filter(child => child.type === 'h3')` - what is that doing? – Mike G May 03 '23 at 02:16
  • Since it already coming as string, it not doing anything.. it come as null or so – soccerway May 03 '23 at 02:30
  • 1
    I don't understand that sentence. The problem is you are trying to perform `filter()` on a string (in the line I showed) but that's not possible since `filter()` acts on an array. – Mike G May 03 '23 at 20:51