Closed kavin-bytive closed 6 months ago
Hi @tjtanjin , i tried importing all 3 of them like this but didn't worked
`// Lazy load the components from react-chatbotify const ChatBot = lazy(() => import('react-chatbotify').then(mod => mod.ChatBot));
const getDefaultBotOptions = lazy(() => import('react-chatbotify').then(mod => mod.getDefaultBotOptions));
const BotOptionsContext = lazy(() => import('react-chatbotify').then(mod => mod.BotOptionsContext)); `
@kavin-bytive Ok so it's a little hard to read with the formatting above 😰
From what I can make off the stuffs above, you can try the following:
getDefaultBotOptions()
within your useEffect
hookBotOptionsProvider
into where the <ChatBot/>
is being lazily loaded as wellconst ChatBot = lazy(() => import("react-chatbotify"));
const {BotOptionsContext} = lazy(() => import("react-chatbotify"));
<>
{isLoaded &&
( <BotOptionsContext.Provider
value={{ botOptions: option, setBotOptions: setOption }}
>
<Suspense fallback={<div>Loading...</div>}>
<ChatBot flow={flow} options={option} />
</Suspense>
</BotOptionsContext.Provider>)
}
</>
error on loading
Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'Provider')
Source
app/component/molecules/MyChatbot.js (225:24) @ Provider
223 | <>
224 | {isLoaded &&
> 225 | ( <BotOptionsContext.Provider
| ^
226 | value={{ botOptions: option, setBotOptions: setOption }}
227 | >
228 |
@kavin-bytive Ok so it's a little hard to read with the formatting above 😰
From what I can make off the stuffs above, you can try the following:
- Call
getDefaultBotOptions()
within youruseEffect
hook- Shift your
BotOptionsProvider
into where the<ChatBot/>
is being lazily loaded as well
sorry for bad formatting, i have edited it :P
@kavin-bytive Give this a try:
"use client";
import { lazy, Suspense, useEffect, useState } from "react"
import { Options } from "react-chatbotify";
export default function Home() {
const [option, setOption] = useState<Options>();
const [BotOptionsContext, setBotOptionsContext] = useState<any>(null);
const ChatBot = lazy(() => import("react-chatbotify"));
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
const loadBotOptions = async () => {
// note: do imports here
const { getDefaultBotOptions, BotOptionsContext } = await import("react-chatbotify");
// note: set bot options and context here
setBotOptionsContext(BotOptionsContext);
const defaultBotOptions = getDefaultBotOptions();
setOption({
...defaultBotOptions,
// note: your other styles here
});
};
loadBotOptions();
setIsLoaded(true);
}, [])
return (
<>
{isLoaded && (
<Suspense fallback={<div>Loading...</div>}>
{BotOptionsContext != null && (
<BotOptionsContext.Provider
value={{ botOptions: option, setBotOptions: setOption }}
>
<ChatBot />
</BotOptionsContext.Provider>)
}
</Suspense>
)}
</>
);
}
"use client";
"use strict";
import { lazy, Suspense, useContext, useEffect, useState } from "react";
// import { useAiState } from "../atom/AistateProvier";
import { useRouter } from "next/navigation";
import { AiStateContext } from "../atom/AistateProvier";
const MyChatBot = () => {
const [form, setForm] = useState({});
const [option, setOption] = useState(null);
const [BotOptionsContext, setBotOptionsContext] = useState(null);
const ChatBot = lazy(() => import("react-chatbotify"));
// const { isOpen, setIsOpen } = useAiState();
const { isOpen, setIsOpen } = useContext(AiStateContext);
const router = useRouter();
useEffect(() => {
const loadBotOptions = async () => {
// note: do imports here
const { getDefaultBotOptions, BotOptionsContext } = await import("react-chatbotify");
// note: set bot options and context here
setBotOptionsContext(BotOptionsContext);
const defaultBotOptions = getDefaultBotOptions();
console.log("🚀 ~ loadBotOptions ~ defaultBotOptions:", defaultBotOptions)
setOption({
...defaultBotOptions,
// note: your other styles here
theme: {
...defaultBotOptions.theme,
embedded: false,
secondaryColor: "#1A3057",
primaryColor: "#077D65",
},
header: {
...defaultBotOptions.header,
title: <h3>AI Assistant!!</h3>,
avatar: "https://img.icons8.com/color/48/message-bot.png",
},
chatHistory: {
...defaultBotOptions.chatHistory,
storageKey: "example_advanced_form",
},
chatButton: {
...defaultBotOptions.chatButton,
icon: "https://img.icons8.com/color/48/message-bot.png",
},
tooltip: {
...defaultBotOptions.tooltip,
mode: "CLOSE",
text: "AI Assistant! 😊",
},
isOpen: isOpen,
advance: {
useCustomBotOptions: true,
},
footer: {
...defaultBotOptions.footer,
text: (
<div style={{ cursor: "pointer" }} onClick={() => router.push("/")}>
<span>Powered By </span>
<span style={{ fontWeight: "bold" }}>
<span> MediXplore.co</span>
</span>
</div>
),
},
});
};
loadBotOptions();
setIsLoaded(true);
}, [])
useEffect(() => {
setOption((prev) => ({ ...prev, isOpen }));
}, [isOpen]);
console.log("&&&&&&&", isOpen);
const fetchMinMax = async () => {
let countryURL = ``;
for (let index in form.countries) {
countryURL += `&filters[$or][${index}][hospital_form][country][id][$eq]=${form.countries[index]}`;
}
const maxURL = `https://cms-backend.medixplore.co/api/hospitaltreatmentprices?sort=max:desc&pagination[page]=1&pagination[pageSize]=1&filters[treatment][id][$eq]=${form.treatment}${countryURL}`;
const getMax = fetch(maxURL);
const minURL = `
https://cms-backend.medixplore.co/api/hospitaltreatmentprices?sort=min&pagination[page]=1&pagination[pageSize]=1&filters[treatment][id][$eq]=${form.treatment}${countryURL}`;
const getMin = fetch(minURL);
const [min, max] = await Promise.allSettled([getMin, getMax]);
const minData = await min.value.json();
const maxData = await max.value.json();
return {
min: minData.data[0].attributes.min,
max: maxData.data[0].attributes.max,
};
};
const flow = {
start: {
message:
"I'm Amy from MediXplore. We help people find the best medical treatments, whether you're looking for options close to home or considering treatment abroad. ",
transition: { duration: 1000 },
path: "init",
},
init: {
message: "Here is list of most popular treatments.",
options: ["Knee replacement", "Heart Bypass surgery", "Spinal Fusion"],
chatDisabled: true,
function: (params) => {
// to be replaced via api calls l
const idMappings = {
"Knee replacement": 3,
"Heart Bypass surgery": 56,
"Spinal Fusion": 51,
};
const val = idMappings[params.userInput];
console.log("val is", val);
setForm({ ...form, treatment: val });
},
path: "ask_countries",
},
ask_countries: {
message:
"Great! To help narrow down your options, tell me, in which country are you generally interested in receiving treatment? We have several destinations known for their quality and affordability. Some top destinations include:",
checkboxes: {
items: ["Singapore", "Malaysia", "Thailand"],
min: 1,
max: 3,
},
chatDisabled: false,
function: (params) => {
const countriesMapping = {
Singapore: 1,
Malaysia: 2,
Thailand: 4,
};
let selections = [];
for (let country of params.userInput.split(",")) {
if (countriesMapping[country.trim()]) {
selections.push(countriesMapping[country.trim()]);
}
}
setForm({ ...form, countries: selections });
console.log("selections", selections);
},
path: "ask_budget",
},
ask_budget: {
message: async (params) => {
const val = await fetchMinMax();
console.log("val", val);
setForm({ ...form, range: val });
return `Wonderful! To give you the most relevant options, it helps to know your budget for the procedure. Minimum: ${val.min}$ Maximum : ${val.max}$`;
},
function: (params) => setForm({ ...form, budget: params.userInput }),
path: async (params) => {
console.log("val is", form.range);
if (isNaN(Number(params.userInput))) {
await params.injectMessage("Budget needs to be a number!");
return;
}
if (params.userInput < form.range.min) {
await params.injectMessage(
`Budget can't be less then specified range i.e. Minimum: ${form.range.min}$ Maximum : ${form.range.max}$`
);
return;
}
return "input_name";
},
},
input_name: {
message: "Kindly enter your name",
chatDisabled: false,
function: (params) => setForm({ ...form, name: params.userInput }),
path: "input_email",
},
input_email: {
message: "Enter your email",
chatDisabled: false,
function: (params) => setForm({ ...form, email: params.userInput }),
path: "input_phone",
},
input_phone: {
message: "Enter your phone number",
chatDisabled: false,
function: (params) => setForm({ ...form, phone: params.userInput }),
path: "prepare_search",
},
prepare_search: {
message:
"Yipee!! Your search results are ready!! Kindly click below to view them!!",
options: ["See Search Results!!", "Retry"],
chatDisabled: true,
path: "process_input",
},
process_input: {
transition: { duration: 0 },
chatDisabled: true,
path: async (params) => {
switch (params.userInput) {
case "See Search Results!!":
let link = `/search?budget=${form.budget}&tr=${form.treatment}`;
for (let country of form.countries) {
link += `&co=${country}`;
}
await params.injectMessage("Sit tight! I'll send you right there!");
setTimeout(() => {
router.push(link);
setIsOpen(false)
}, 1000);
return "repeat";
case "Retry":
return "repeat";
break;
}
},
},
repeat: {
transition: { duration: 1000 },
path: "start",
},
};
const [isLoaded, setIsLoaded] = useState(false);
// useEffect(() => {
// setIsLoaded(true);
// }, []);
return (
<>
{isLoaded && (
<Suspense fallback={<div>Loading...</div>}>
{BotOptionsContext != null && (
<BotOptionsContext.Provider
value={{ botOptions: option, setBotOptions: setOption }}
>
<ChatBot flow={flow} options={option}/>
</BotOptionsContext.Provider>)
}
</Suspense>
)}
</>
);
};
export default MyChatBot;
tried this, but still getting same error @tjtanjin
ReferenceError: window is not defined
at 90180 (/Users/kavinsharma/Desktop/work/MediExplore/.next/server/chunks/180.js:2:5739)
at t (/Users/kavinsharma/Desktop/work/MediExplore/.next/server/webpack-runtime.js:1:127)
at 72098 (/Users/kavinsharma/Desktop/work/MediExplore/.next/server/app/page.js:1:3287)
at t (/Users/kavinsharma/Desktop/work/MediExplore/.next/server/webpack-runtime.js:1:127)
at F (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:94693)
at j (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:93244)
at rP (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:33905)
at nN (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:62423)
at nB (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:67657)
at nF (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:66824)
Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error
ReferenceError: window is not defined
at 90180 (/Users/kavinsharma/Desktop/work/MediExplore/.next/server/chunks/180.js:2:5739)
at t (/Users/kavinsharma/Desktop/work/MediExplore/.next/server/webpack-runtime.js:1:127)
at 72098 (/Users/kavinsharma/Desktop/work/MediExplore/.next/server/app/page.js:1:3287)
at t (/Users/kavinsharma/Desktop/work/MediExplore/.next/server/webpack-runtime.js:1:127)
at F (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:94693)
at j (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:93244)
at rP (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:33905)
at nN (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:62423)
at nB (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:67657)
at nF (/Users/kavinsharma/Desktop/work/MediExplore/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js:12:66824)
@tjtanjin finally it worked, above codebase i have shared is working fine by moving things to use-effect https://github.com/tjtanjin/react-chatbotify/issues/32#issuecomment-2054187127, i missed to remove the import from another file, due to which it was not working.
thanks again for quick response and creating this amazing package.
Bug Description
Code Snippet
as per given solution in this issue https://github.com/tjtanjin/react-chatbotify/issues/19 it works to import the
ChatBot
but i am also usinggetDefaultBotOptions
andBotOptionsContext
and they are not working while trying with lazy function.