zenoamaro / react-quill

A Quill component for React.
https://zenoamaro.github.io/react-quill
MIT License
6.78k stars 923 forks source link

TypeError: moduleClass is not a constructor in React-Quill with Quill Mention Module #999

Open Kuldeeptak-neelnetworks opened 2 months ago

Kuldeeptak-neelnetworks commented 2 months ago

I'm encountering an error while integrating the quill-mention module with react-quill in a Next.js application. The error message I see is:

Unhandled Runtime Error TypeError: moduleClass is not a constructor

Call Stack SnowTheme.addModule (node_modules/react-quill/node_modules/quill/dist/quill.js (6130:0)) SnowTheme.addModule (node_modules/react-quill/node_modules/quill/dist/quill.js (6774:0)) eval (node_modules/react-quill/node_modules/quill/dist/quill.js (6122:0)) Array.forEach

SnowTheme.init Here is how I’m trying to use the quill-mention module: "use client"; import React, { Dispatch, SetStateAction, useEffect, useState } from "react"; import dynamic from "next/dynamic"; import Quill from "quill"; import Mention from "quill-mention"; import "react-quill/dist/quill.snow.css"; import { Button } from "@/components/ui/button"; import { Loader2 } from "lucide-react"; import TooltipCommon from "@/components/common/TooltipCommon"; import { useCopywriterStore } from "@/Store/CopywriterStore"; import { useUserStore } from "@/Store/UserStore"; import { useEditorStore } from "@/Store/EditorStore"; // Dynamically import ReactQuill to prevent SSR issues const ReactQuill = dynamic(() => import("react-quill"), { ssr: false }); interface QuillEditorProps { customerId: string | string[]; updateId: string | string[]; indicatorText: string | string[]; handleEdit: string | string[]; orderId: string | string[]; productFlowId: string | string[]; leadId: string | string[]; technicalId: string | string[]; copywriterId: string | string[]; amendmentId: string | string[]; websiteContentId: string | string[]; setIsOpenReplyModel: Dispatch>; setOpenQuill: Dispatch>; } const QuillEditor: React.FC = ({ customerId, setIsOpenReplyModel, setOpenQuill, updateId, productFlowId, orderId, technicalId, leadId, indicatorText, amendmentId, copywriterId, websiteContentId, handleEdit, handlesave, editContent, }: any) => { const [value, setValue] = useState(""); const [images, setImages] = useState([]); const [isLoading, setIsLoading] = useState(false); const [fileURLs, setFileURLs] = useState<{ [key: string]: string }>({}); const { fetchCopywriterData }: any = useCopywriterStore(); const { fetchUsersData, userData } = useUserStore(); const { fetchEditorData, fetchLeadsEditorData, fetchOrderEditorData, fetchTechnicalUpdateData, fetchAmendmentUpdateData, fetchProductFlowUpdateData, fetchWebsiteContentUpdateData, orderEditorData, fetchCopywriterUpdateData, editorData, addReplyData, addUpdateData, loading, }: any = useEditorStore(); const handleClear = () => { setValue(""); }; const handleChanges = (value: string, editorData: any) => { setValue(() => editorData.getText().trim() === "" && value === "" ? "" : value ); }; const handleAddData = async (e: React.FormEvent) => { e.preventDefault(); if ((value !== "" && value !== "


") || images.length > 0) { try { setIsLoading(true); const formData = new FormData(); formData.append("content", value); images.forEach((image) => formData.append("files", image)); const requests = []; if (indicatorText === "post") { requests.push( orderId && baseInstance.post(`/updates/order/${orderId}`, formData), productFlowId && baseInstance.post( `/updates/productflow/${productFlowId}`, formData ), customerId && baseInstance.post(`/updates/customer/${customerId}`, formData), leadId && baseInstance.post(`/updates/lead/${leadId}`, formData), technicalId && baseInstance.post( `/updates/technicaltracker/${technicalId}`, formData ), copywriterId && baseInstance.post( `/updates/copywritertracker/${copywriterId}`, formData ), websiteContentId && baseInstance.post( `/updates/newwebsitecontent/${websiteContentId}`, formData ), amendmentId && baseInstance.post(`/updates/amendment/${amendmentId}`, formData) ); } if (indicatorText === "reply") { requests.push( baseInstance.post(`/updates/update/reply/${updateId}`, formData) ); } const responses = await Promise.all(requests.filter(Boolean)); responses.forEach((response) => { if (response.status === 201) { successToastingFunction(response?.data?.message); fetchEditorData(customerId); fetchOrderEditorData(orderId); fetchLeadsEditorData(leadId); fetchTechnicalUpdateData(technicalId); fetchCopywriterUpdateData(copywriterId); fetchAmendmentUpdateData(amendmentId); fetchProductFlowUpdateData(productFlowId); fetchWebsiteContentUpdateData(websiteContentId); setIsOpenReplyModel(false); setOpenQuill(false); handleClear(); setImages([]); setValue(""); } fetchEditorData(customerId); }); } catch (error) { errorToastingFunction(error); } finally { setIsLoading(false); } } else { errorToastingFunction("Please enter text or upload an image to submit."); } }; const handleFileUpload = (files: FileList | null) => { if (files) { const fileList = Array.from(files); setImages((prevImages) => [...prevImages, ...fileList]); fileList.forEach((file) => { if (file.type.startsWith("image/")) { const reader = new FileReader(); reader.onloadend = () => { const img = `${file.name}`; setValue((prevValue) => prevValue + img + `
`); }; reader.readAsDataURL(file); } else { const url = URL.createObjectURL(file); setFileURLs((prev) => ({ ...prev, [file.name]: url })); const link = `${file.name}`; setValue((prevValue) => prevValue + link + `
`); } }); } }; const imageHandler = () => { const inputImage = document.createElement("input"); inputImage.setAttribute("type", "file"); inputImage.setAttribute( "accept", "image/*, video/*, .pdf, .xlsx, .doc, .docx" ); inputImage.setAttribute("multiple", "true"); inputImage.click(); inputImage.onchange = (e) => { handleFileUpload(inputImage.files); }; }; useEffect(() => { return () => { Object.values(fileURLs).forEach((url) => URL.revokeObjectURL(url)); }; }, [fileURLs]); // Commented out because it causes an error // useEffect(() => { // if (Quill) { // Quill.register("modules/imageResize", ImageResize); // Quill.register("modules/mention", Mention); // } // }, [Quill]); const toolbarOptions = [ ["bold", "italic", "underline", "strike"], [{ size: ["small", false, "large", "huge"] }], [{ list: "ordered" }, { list: "bullet" }, { list: "check" }], [{ script: "sub" }, { script: "super" }], [{ indent: "-1" }, { indent: "+1" }], [{ direction: "rtl" }], [{ color: [] }, { background: [] }], [{ font: [] }], [{ align: [] }], ]; const options = { debug: "info", modules: { toolbar: toolbarOptions, imageResize: { parchment: Quill.import("parchment"), modules: ["Resize", "DisplaySize"], }, mention: { allowedChars: /^[A-Za-z\s]*$/, mentionDenotationChars: ["@"], source: async ( searchTerm: string, renderItem: (data: any[]) => void ) => { try { await fetchUsersData(); // Ensure data is fetched first const filteredUsers = userData .filter((user: any) => user.name.toLowerCase().includes(searchTerm.toLowerCase()) ) .map((user: any) => ({ value: user.name })); renderItem(filteredUsers); } catch (error) { console.error("Error fetching mention users:", error); renderItem([]); } }, }, }, placeholder: "Compose an epic...", theme: "snow", }; return ( <>
{ handleChanges(value, editor); }} />
); }; export default QuillEditor; Question: I've integrated the quill-mention module into my react-quill component but am running into an issue. The error TypeError: moduleClass is not a constructor appears, and the call stack indicates a problem with SnowTheme.addModule in the Quill.js file. I've tried to register the module as follows: `useEffect(() => { if (Quill) { Quill.register("modules/imageResize", ImageResize); Quill.register("modules/mention", Mention); } }, [Quill]);` However, this causes the mentioned error. I've also commented out the registration as it seems to be the cause of the issue. What I've Tried: Ensuring that the quill-mention module is correctly imported and used. Checking the version compatibility of react-quill, quill, and quill-mention. Referencing the Quill documentation for proper module registration. What I Need Help With: Why am I encountering this TypeError? How can I properly integrate the quill-mention module with react-quill? Are there any additional steps or configurations required to avoid this error? Any guidance or suggestions would be greatly appreciated! This is the Error:- ![image](https://github.com/user-attachments/assets/91c8d9d6-1746-491f-a8df-06efb71473b4)
Kuldeeptak-neelnetworks commented 2 months ago

"quill": "^2.0.2", "quill-image-resize-module-react": "^3.0.0", "quill-image-resize-module-ts": "^3.0.3", "quill-mention": "^6.0.1", "react-quill": "^2.0.0",

these are the versions.
package,json
kaushik-codal commented 2 months ago

I'm also facing same issue. Let me know if any solution found?

Kuldeeptak-neelnetworks commented 1 month ago

hello did you find the solution?? I am still searching but didn't find.. should we change in node Modules package.?

Kuldeeptak-neelnetworks commented 1 month ago

Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'unshift')

Call Stack new Mention (app-pages-browser)\node_modules\quill-mention\dist\mention.mjs (57:36) SnowTheme.addModule (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6130:0) SnowTheme.addModule (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6774:0) eval (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6122:0) Array.forEach

SnowTheme.init (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6120:0) new Quill (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (1163:0)
Kuldeeptak-neelnetworks commented 1 month ago

"quill": "^2.0.2", "quill-image-resize-module-react": "^3.0.0", "quill-image-resize-module-ts": "^3.0.3", "quill-mention": "^6.0.1",

zakriayounas commented 4 weeks ago

Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading 'unshift')

Call Stack new Mention (app-pages-browser)\node_modules\quill-mention\dist\mention.mjs (57:36) SnowTheme.addModule (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6130:0) SnowTheme.addModule (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6774:0) eval (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6122:0) Array.forEach SnowTheme.init (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (6120:0) new Quill (app-pages-browser)\node_modules\react-quill\node_modules\quill\dist\quill.js (1163:0)

could you please mention me when you got the solution same error facing

Annastrin commented 3 weeks ago

+1 Also having this issue with these versions of react-quill and quill-mention. quill Cannot import modules/mention. Are you sure it was registered? Uncaught TypeError: moduleClass is not a constructor

iamdipansh commented 3 weeks ago

+1 Also having this issue with these versions of react-quill and quill-mention. quill Cannot import modules/mention. Are you sure it was registered? Uncaught TypeError: moduleClass is not a constructor

+1 Having the same issue, do let me know if you find the solution.