Build a Markdown Previewer - can't update components

Tell us what’s happening:
I want to pass state to both my #editor and #preview components, so as I type into #editor, #preview also updates. Everything seems fine, but #preview is not updating. I’m missing something, but can’t figure out what

Your code so far

const instructions = 
`# headers
*emphasis*  
**strong**
*list
>block quote
code (4 spaces indent)
[links] wikipedia.org`

const defaultText =
`
#hey, this is my sample header

let me put some emphasis on *something*

be **strong**

let me list 3 things
  *one thing
  *two things
  *three things

>I really like block code
  or code inside text

you should check this [link]
`

//COMPONENTS

function Rules() {//the rules box on the left side
  return(
    
      <div className="wrapper">
        <h2 className="title-bar">Quick Reference</h2>
        <textarea id="rules">{instructions}</textarea>
      </div>
     
  )
}

function TextArea(props) {//THE EDITOR AREA
  return(
      <div className="wrapper">
        <div className="title-bar">
          <h2>Type your text here</h2>
        </div>
        <textarea id="editor">{props.content}</textarea>
      </div>
    ) 
}

function Results(props) {//AFTER THE MARKDOWN IS APPLIED
  return(
    <div className="wrapper">
      <div className="title-bar">
        <h2>See the results here</h2>
      </div>  
      <textarea id="preview">{props.content}</textarea>
    </div>
  )  
}

//i need to update the results box as I type on the editor box.
//I'll have to handle changes on the editor box, save that to state and pass on to results
//Results should have an initial state that is the same as editor

class App extends React.Component{
  constructor(props){
    super(props)
      this.state = {
        content: defaultText
      }
    this.handleChange = this.handleChange.bind(this);
  }
  
  handleChange(e){//takes user input
    this.setState({content: e.target.value})
  }
  
  render(){
    
    return(
      <div className="container">
        <Rules />
        <TextArea content={this.state.content} onKeyUp={this.handleChange} />
        <Results content={this.state.content} />  
      </div>
    )
  }
  
}

ReactDOM.render(<App />, document.getElementById('app'))

Your browser information:

Chrome Version 71.0.3578.98 (Official Build) (64-bit)

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/front-end-libraries/front-end-libraries-projects/build-a-markdown-previewer

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make easier to read.

See this post to find the backtick on your keyboard. The “preformatted text” tool in the editor (</>) will also add backticks around text.

Note: Backticks are not single quotes.

markdown_Forums

2 Likes

On this one you have to use the marked.js library. See user story #4 in the instructions. It is pretty easy to use, just feed it some markdown and out comes the markup.

1 Like

thanks! Sorry, I’m new here.

Thanks! I’m not at that stage yet, I can’t get the preview area to update with what I type on the editor area

You have 3 Problems,

  1. Your onChange() method in the TextArea component is not being passed to the parent component to the real textarea, you need to pass it as a callback like so,
    <textarea id="editor" onChange={props.onChange}>{props.content}</textarea>

  2. In your handlechange event you need to use event.target.value to get the value of the text area and update the state, i don’t think event.target has a property called content

  3. Your results component has a property called value that you need to update withe the state’s value, like so, no need to update it’s value as it’s own entry
    <textarea id="preview" value={props.content}></textarea>

let me know if anything is unclear

2 Likes

Thanks, Dereje. I’ll work on these. I figured I had something wrong with the onChange, but couldn’t understand what. This is very helpful

That did the trick! Thank you so much

Hi, can u please tell me how to use that library inorder to convert ?..my only problem lies in that…i have spent so many hours trying and i’ve failed to notice what syntax exactly do i need to write inorder to make the conversion.

At this point you should consult the documentation of the library (marked.js). Just google it. It is really good to start getting used to doing this. The documentation is pretty good. If you have a hard time interpreting the documentation ask again.

1 Like

Just one tip that really helped me. You need to use dangerouslySetInnerHtml to get the proper markdown. Other methods didn’t fully apply the styles in my case. But like Tom said, the documentation is the way to go. It also took me a while to get it going

1 Like

Scorpio, if you are completely exasperated just take a look at this codepen: markdown. Also note the use of dangerouslySetInnerHTML as Gus mentioned.

1 Like

Thanx Gus and Mr.Harplinge, i did find the documentation but i had a very hard time interpreting it and the farthest points i reached was using marked() which didnt do the trick all by itself so after more hours i used the dangerous thing but without putting __html in it and as u can guess it didn’t work as it should then i spent many hours more and reached a dead end so…you can imagine how frustrated i was :smiley:

Did you figure it out Scorpio? I hope you understand it all now. :slight_smile:

1 Like

yea i did thanks :smiley: …now the only test i can’t pass is the first optional one which is opening the links of the markdown in a new tab…spent many hours researching only found people saying it can’t be done and the ones who did it use regex and not the library.

The only trick I could find to opening links in a new tab is to customize the render in marked.js,
reference: https://marked.js.org/#/USING_PRO.md#renderer

took me a little bit of searching and trial and error to figure out.

1 Like

You can just type in plain HTML to do that. For example, try

<a href="#" target="_blank">link</a>

That seems to do the trick.

The user story asks for the rendered link to open in a new tab. not a manual HTML entry

When I click a link rendered by my markdown previewer, the link is opened up in a new tab (HINT: read the Marked.js docs for this one!).

Marked.js will render that html a-tag as a link. And it will open in a new tab.

Input into Marked.js inside your textarea with an id="editor" should be this:

[links](https://www.freecodecamp.org "fCC")

Output should be a link that opens in a new tab.