Markdown Previewer - Code all works but I am failing on 3, 4 and 7

Hi,

I am having issues finishing this project everything seems to work but freecodecamp tests are returning failed for 3, 4 and 7. I am unsure how to fix this issue as the code is working fine when I test manually. The code base can be found here: GitHub - Joseph-Worthington/markdown-previewer

Also I will provide the snippets for the main three files.

App:

import React, {useState} from 'react';
import Editor from './components/Editor';
import Preview from './components/Preview';
import DefaultText from './components/DefaultText';
import DarkMode from './components/DarkMode';

function App() {
  const [value, setValue] = React.useState<string>(DefaultText);
  const [dark, setDark] = useState(false)
    
  const onChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
      setValue(event.target.value);
  }
  const toggleTheme = () => {
    setDark(!dark)
    document.body.classList.toggle('dark')
  }
  if(document.body.classList.contains('dark') && !dark){
    setDark(true)
  }
  

  return (
    <div className="App p-10 bg-slate-500 dark:bg-slate-900 flex flex-col items-center min-h-screen">
      <div className="relative w-[80%] px-10 flex flex-col">
        <DarkMode dark={dark} toggleTheme={toggleTheme}/>
        <h1 className="text-3xl text-center">Markdown Previewer</h1>       
      </div>
      <div className=" flex justify-evenly gap-10 py-10 xl:p-10 w-[80%] flex-wrap xl:flex-nowrap">
      <Editor onChange={onChange} value={value}/>
      <Preview value={value}/>
      </div>
    </div>
  );
}

export default App;

Editor

import React from 'react';

interface EditorProps {
  value: string;
  onChange: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
}

const Editor: React.FC<EditorProps> = ({ value, onChange }) => {

  return (
    <div className='bg-slate-200 dark:bg-slate-700 border-2 border-solid border-black p-10 w-full xl:w-[40%] min-h-96'>
      <h2>Editor</h2>
      <textarea id="editor" onChange={onChange} value={value} className='w-full min-h-[80%] p-5 dark:bg-gray-800 dark:text-slate-50'/>
    </div>
  );
}

export default Editor;

Previewer:

import React, { useEffect, useState } from 'react';
import { marked } from 'marked';

interface PreviewProps {
    value: string;
}

const Preview: React.FC<PreviewProps> = ({ value }) => {
    const [markdown, setMarkdown] = useState('');

    useEffect(() => {
        marked.setOptions({
            gfm: true,
            breaks: true
        });

        Promise.resolve(marked(value)).then(setMarkdown);
    }, [value]);

    return (
        <div className=' bg-slate-200 dark:bg-slate-700 border-2 border-solid border-black p-10 xl:w-[60%]  w-full'>
            <h2 className='w-1.5'>Preview</h2>
            <div id="preview" dangerouslySetInnerHTML={{ __html: markdown }}></div>
        </div>
    );
}

export default Preview;

Any help or advice would be greatly appreciated thank you.

Can you post the link to these challenges or the markdown previewer page?

Sure, just got that setup on github pages.

You can see it all here React App

Remove the Promise.resolve from the useEffect.

If it is because of the type, you could use the return type given in the marked hover hint string | Promise<string> as a generic to useState.


When I replace the promise code, it passes all the tests.

Hi sorry, I am still new to this stuff with TypeScript. I am not sure how to write this without getting errors, I am unable to make the string | Promise work, I am just getting this error

Argument of type 'string | Promise<string>' is not assignable to parameter of type 'SetStateAction<string>'.
  Type 'Promise<string>' is not assignable to type 'SetStateAction<string>'
useState<string | Promise<string>>("");

You could also use a as string type assertion at the call site.

setMarkdown(marked(value) as string);

The option for a promise is related to extensions (so asserting it is a string, as long as it is a string and not a promise, should be fine).

marked.d.ts

/**
 * Compiles markdown to HTML.
 *
 * @param src String of markdown source to be compiled
 * @param options Optional hash of options
 * @return String of compiled HTML. Will be a Promise of string if async is set to true by any extensions.
 */
export declare function marked(src: string, options?: MarkedOptions): string | Promise<string>;

Thank you.

That was really helpful