Hi,
I am not sure about the exact reason, but when dinamically routing to the page or rendering the component when user data is fetched for HeaderUserMenu, the menu is not opening on click. I have to make a full page reload in order for it to work. How can one ensure the menu is working even if the component is rendered dynamically or conditionally?
Best regards,
Hi Carmelo,
Thank you for checking it out.
You are right, it seems that the reinitialization was not the problem. After some further testing it looks like the issue is being generated by using the RTK Query hooks. I still need to do some tests to find out the right way to implement that, but the good news is that the theme is working as expected when the conditional value is in local state.
Thank you for helping me get to the bottom of this.
Best wishes,
Tamás
Hi there,
I managed to recreate the issue for you so you may be able to test it on the react demo2. Please try out this code in i18nProvider.tsx and see that after login, the HeaderUserMenu is not opening on click.
const I18nProvider: FC<WithChildren> = ({children}) => {
const locale = useLang()
const messages = allMessages[locale]
const [loading, setLoading] = useState(true)
useEffect(() => {
setLoading(true)
setTimeout(() => {
setLoading(false)
}, 2000)
}, [])
return loading ? (
<FallbackView />
) : (
<IntlProvider locale={locale} messages={messages}>
{children}
</IntlProvider>
)
}
export {I18nProvider}
Hi,
I've just checked your case, and all menus works, without any changes and extra re-initialization (I changed I18nProvider as you mentioned above).MasterInit
is a child element of I18nProvider
and it handles all menus/toggles re-initialization inside the app.
My code of I18nProvider
:
import {FC, useEffect, useState} from "react"
import {useLang} from "./Metronici18n"
import {IntlProvider} from "react-intl"
import "@formatjs/intl-relativetimeformat/polyfill"
import "@formatjs/intl-relativetimeformat/locale-data/en"
import "@formatjs/intl-relativetimeformat/locale-data/de"
import "@formatjs/intl-relativetimeformat/locale-data/es"
import "@formatjs/intl-relativetimeformat/locale-data/fr"
import "@formatjs/intl-relativetimeformat/locale-data/ja"
import "@formatjs/intl-relativetimeformat/locale-data/zh"
import deMessages from "./messages/de.json"
import enMessages from "./messages/en.json"
import esMessages from "./messages/es.json"
import frMessages from "./messages/fr.json"
import jaMessages from "./messages/ja.json"
import zhMessages from "./messages/zh.json"
import {WithChildren} from "../helpers"
const allMessages = {
de: deMessages,
en: enMessages,
es: esMessages,
fr: frMessages,
ja: jaMessages,
zh: zhMessages,
}
const I18nProvider: FC<WithChildren> = ({children}) => {
const locale = useLang()
const messages = allMessages[locale]
const [loading, setLoading] = useState(false)
useEffect(() => {
setLoading(true)
setTimeout(() => {
setLoading(false)
}, 10000)
}, [])
return loading ? (
<div>Loading ... </div>
) : (
<IntlProvider locale={locale} messages={messages}>
{children}
</IntlProvider>
)
}
export {I18nProvider}
FallbackView
in our sources (maybe smth wrong with this FallbackView
component).Hi Carmelo,
I don't see how this ticket got the 'resolved' status, the issue is not solved, as stated in my last comment. Do you have any suggestions for a workaround at least if the fix is not in sight?
Thank you for your help.
Hi Tamás,
Not sure how we can help with this. cause, we aren't able to reproduce your custom code. We can keep it as 'unresolved' but in that case, I will not be able to receive notifications about new answers in the thread.
Anyway, try to check User management module src/app/modules/apps/user-management/users-list
.
Here is a lot of dynamic rendering (including fetching the data from the server and rendering them + conditional rendering) with working menus:
1) Actions component (Actions menu in the table): src/app/modules/apps/user-management/users-list/table/columns/UserActionsCell.tsx
2) Filter: src/app/modules/apps/user-management/users-list/components/header/UsersListFilter.tsx
Regards,
Keenthemes support
That's unfortunate. Anyway, thanks for the tips. I have no issue anywhere else with conditional rendering and fetching data from the server. Only this issue I am having with the i18nProvider and the Menus. What to do, I'll try to refactor the logic and see if I can circumvent this.
Thank you for looking at it.
Best wishes,
Yes, isLoading is there in the deps array of I18nProvider useEffect.
Hi,
That didn't help, but I've found that the issue was not caused in that component. Earlier I have implemented some logic for the I18nProvider component, where I fetch the user language from the backend.
I have this in the I18nProvider.tsx:
return isLoading ? (
<LoadingView />
) : (
<IntlProvider locale={locale} messages={messages}>
{children}
</IntlProvider>
Hi,
In that case try to add isLoading
into the useEffect into the deps array.
Regards,
Keenthemes support
Also, you can write a wrapper component for your {children}
and call re-init when this component will be mounted into the DOM.
Regards,
Keenthemes support
Did you mean like this:
const Wrapper: FC<WithChildren> = ({children}) => {
useEffect(() => {
MenuComponent.reinitialization()
}, [])
return <>{children}</>
}
Hi,
Wrap MenuComponent.reinitialization()
into setTimout
, we have to be sure that your component is already mounted. *You can check example in src/_metronic/layout/MasterInit.tsx
file.
Also you haven't added ToggleComponent
reinitialization also.
Regards,
Keenthemes support
const Wrapper: FC<WithChildren> = ({children}) => {
useEffect(() => {
setTimeout(() => {
ToggleComponent.bootstrap()
MenuComponent.bootstrap()
}, 1500)
}, [])
return <>{children}</>
}
Hi Carmelo,
I made a very simple modification in the TopBar.tsx in Metronic Demo2 so you can test the logic. I am using RTK Query to get the user and pass it as a prop to HeaderUserMenu component. I have tested user, isLoading, isSuccess properties for updating the component without any success.
I have also tried to move the fetching logic into the HeaderUserMenu, but the results is the same.
https://gist.github.com/tom3rr/dd4a2cdaf19554e2dc899b43c06e55e7
What am I missing?
Thanks for your help,
Tamás
Hi,
Try also add ToggleComponent.bootstrap()
,
Maybe it will help to active toggling. Quite not sure, but other things looks fine.
Regards,
Keenthems support
Hi Carmelo,
I tried your suggestion, it still doesn't work. I don't understand why is this strange behaviour. I would simply like to load the user data from the backend and render the name in the HeaderUserMenu. After login, when the page is redirected it doesn't work, on refreshing the page it works again. MenuComponent.reinitialization does not seem to have any effect, no matter what the dependency array on useEffect is.
How could this be done properly?
Thank you for your help.
Hi,
Please share with us how you implemented it (you can use GitHub gist for it), maybe we can try to check it.
Regards,
Keenthemes support
Hi Carmelo,
I've added the code to the HeaderUserMenu component like this:
useEffect(() => {
setTimeout(() => {
MenuComponent.reinitialization()
}, 500)
}, [])
Hi,
In useEffect in the dependencies array, you can add location
from const location = useLocation();
.
Then it will re-init the menu when you route to the page.
Regards,
Keenthemes support
Hi,
Once your HeaderUserMenu is ready and mounted to the DOM, you can run: setTimeout(() => {
MenuComponent.reinitialization()
}, 500)import {MenuComponent} from '{pass_to_assets}assets/ts/components'
.
It will re-init your menu then.
Regards,
Keenthemes support