How to populate editorJS on NextJS load with Firestore DB in Firebase

97 views Asked by At

I am trying to populate my editorJS component by fetching the document data from firebase firestore database.

I am using fetchContext function that runs on page load using useEffect, which runs setEditorData that gets passed down to Editor component.

  1. I am not sure if this is the best way to fetch the document field data; it works, but is there a cleaner way to do this?
  2. How can I populate the editor component with this data I retrieve from database? It doesn’t seem to populate correctly, it always shows blank screen although console.log(editorData) in DraftPage.tsx is returning the correct data

Code:

DraftPage.tsx

const DraftPage = () => {
  const router = useRouter();
  const { id } = router.query;
  const [editorData, setEditorData] = useState<OutputData>({} as OutputData);

  const { data: session } = useSession();

  const fetchContext = async () => {
    if (session && session.user && session.user.id) {
      const docRef = doc(db, "users", session?.user?.id!, "drafts", id);
      const docSnap = await getDoc(docRef);
      if (docSnap.exists()) {
        setEditorData(docSnap.data().editorData);
        console.log(editorData); // This is printing the correct data I want
      } else {
        console.log("No such document!");
      }
    }
  };

  useEffect(() => {
    fetchContext();
  }, [session]);

  return (
    <DraftPanel
          session={session}
          editorData={editorData}
          setEditorData={setEditorData}
          draftId={id}
    />
  );
};

export default DraftPage;

DraftPanel.tsx

type DraftPanelProps = {
  session: Session | null;
  draftId: string | string[] | undefined;
  editorData: OutputData;
  setEditorData: Dispatch<SetStateAction<OutputData>>;
};

const EditorBlock = dynamic(() => import("../editor/Editor"), {
  ssr: false,
});

const DraftPanel = ({
  session,
  draftId,
  editorData,
  setEditorData,
}: DraftPanelProps) => {

  return (

    <EditorBlock
      data={editorData}
      onChange={setEditorData}
      holder="editorjs-container"
    />
  );
};

export default DraftPanel;

../editor/Editor.tsx

import React, { memo, useEffect, useRef } from "react";
import EditorJS, { OutputData } from "@editorjs/editorjs";

type Props = {
  data?: OutputData;
  onChange(val: OutputData): void;
  holder: string;
};

const EditorBlock = ({ data, onChange, holder }: Props) => {
  const ref = useRef<EditorJS>();

  // initialize editorjs
  useEffect(() => {
    // initialize editor if we don't have a reference
    if (!ref.current) {
      const editor = new EditorJS({
        holder,
        data,
        minHeight: 30,
        async onChange(api, event) {
          const data = await api.saver.save();
          onChange(data);
        },
      });
      ref.current = editor;
    }
    return () => {
      if (ref.current && ref.current.destroy) {
        ref.current.destroy();
      }
    };
  }, []);

  return <div className="px-16 pt-8" id={holder} />;
};

export default memo(EditorBlock);

Firebase Object Format:

enter image description here

0

There are 0 answers