Topic: MDBToast is not show up
karluk priority asked 1 year ago
Expected behavior*_show toaster on the top right corner._*Actual behavior*_nothing show up_*Resources (screenshots, code snippets etc.)
<template>
<MDBToast v-model="notification.show" :id="notification.id" autohide :delay="notification.delay" appendToBody
position="top-right" stacking width="350px" :toast="notification.status">
<template #title>
{{ notification.title }}
</template>
<template #small>
</template>
{{ notification.message }}
</MDBToast>
import { MDBToast } from "mdb-vue-ui-kit";import { ref } from 'vue';import { INotification } from '../models/notification';
const props = defineProps({
notification: { type: Object as () => INotification, default: { id: "test", title: "Report", message: "Success", status: "success", delay: 5000, show: true } }}); const notification = ref(props.notification);
karluk priority answered 1 year ago
Here is Parent page:
<template>
<span v-for="(notification, i) in notifications">
<Notification :message="notification.message" :title="notification.title" v-model="notifications[i].show"
:delay="notification.delay" :status="notification.status" :id="notification.id" :show="notification.show" />
</span>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import Notification from './Notification.vue'
import { useStore } from "vuex";
import { INotification } from '../models/notification';
const store = useStore();
const notifications = ref([])
watch(() => store.state.notifications.length, async () => {
notifications.value = [...store.state.notifications]})
</script>
Bartosz Cylwik staff commented 1 year ago
I managed to use vuex to show and update the toast.
Parent
<template>
<div v-if="store.state.notifications.length > 0">
<span v-for="(notification, i) in store.state.notifications">
<Notification :notify="notification" />
</span>
</div>
<MDBBtn @click="handleClick">Click</MDBBtn>
</template>
<script setup lang="ts">
import Notification from "./components/HelloWorld.vue";
import { useStore } from "vuex";
import { MDBBtn } from "mdb-vue-ui-kit";
const store = useStore();
const handleClick = async () => {
await store.dispatch("change", [
{
title: "Title 2",
id: "test2",
message: "Danger",
status: "danger",
delay: 5000,
show: true,
},
]);
};
</script>
Child
<template>
<MDBToast
v-model="content.show"
autohide
:delay="content.delay"
appendToBody
position="top-right"
:stacking="true"
width="350px"
:toast="content.status"
@close="removeNotification(content.id)"
>
<template #title> {{ content.title }} - {{ content.id }} </template>
<template #small> </template>
{{ content.message }}
</MDBToast>
</template>
<script setup lang="ts">
import { MDBToast } from "mdb-vue-ui-kit";
import { useStore } from "vuex";
import { ref, onMounted, watch } from "vue";
const props = defineProps({
notify: {
type: Object,
required: true,
},
});
// const store = useStore();
const removeNotification = async (id: string) => {
// await store.dispatch("removeNotification", id);
};
const content = ref({});
watch(
() => props.notify,
(curr) => {
content.value = curr;
}
);
onMounted(() => {
content.value = props.notify;
});
</script>
Make sure to have your getters, mutations and actions properly set so that the changes will be visible in watchers.
karluk priority commented 1 year ago
Thank you for response, Yes it shows the Toaster(s), but when the delay timeout, it won't hide, and throw an exception(I had same issue before as well). the error msg: Uncaught Error: [vuex] do not mutate vuex store state outside mutation handlers.
Bartosz Cylwik staff commented 1 year ago
We've tried to recreate your issue in a plain MDB project, and there seems to be no issue with a fresh install.
Please note, that we can only help you, if the issue is in the package itself. If the issue is caused by an external dependency or custom code, this would be out of product support scope.
We can provide broader consulting, or a video session as a separate service. If you're interested, please reach out to services@mdbootstrap.com & describe your issue in detail.
karluk priority commented 1 year ago
Hi there,
Based on your feedback, I checked my mdb-vue-ui-kits version and it was 3.1.1, and I upgraded to 4.1.1. After update it, I have an issue. my application won't start up. I received an error said: Uncaught SyntaxError: ambiguous indirect export: MDBSideNavMenu.
Please I need help as soon as possible.
Thank you
karluk priority commented 1 year ago
Hi Bartosz,
I updated my package.json file based on your github example, and the application back to normal, but the Toaster throw exception after delay time out. I don't see any example you are using with vuex. Any suggestion please?
Here is my package.json file
"dependencies": {
"dotenv": "^16.3.1",
"mdb-vue-calendar": "./plugins/mdb-vue-calendar-3.2.0.tgz",
"mdb-vue-file-upload": "./plugins/mdb-vue-file-upload-2.2.0.tgz",
"mdb-vue-table-editor": "./plugins/mdb-vue-table-editor-2.2.0.tgz",
"mdb-vue-ui-kit": "./mdb/mdb-vue-ui-kit-4.1.1.tgz",
"vue": "^3.2.40",
"vue-router": "^4.1.5",
"vuex": "^4.0.2"
},
"devDependencies": {
"@types/node": "^20.8.6",
"@vitejs/plugin-vue": "^3.1.0",
"sass": "^1.52.1",
"typescript": "^4.6.4",
"vite": "^3.1.0",
"vue-tsc": "^0.40.4"
}
Bartosz Cylwik staff commented 1 year ago
You can find example with vuex in my comment above.
karluk priority commented 1 year ago
Hello Bartosz,
I don't see any usage vuex data in your Toaster example. Have you ever try it with Vuex please?
Thank you,
Bartosz Cylwik staff commented 1 year ago
Hello, the vuex is used in the Parent component of the example I've shown as an answer to this message. I didn't use vuex inside the Child.
<span v-for="(notification, i) in store.state.notifications">
<Notification :notify="notification" />
</span>
In this example, the value from the store is beeing provided to the Child as a prop. After you provide your own state, the app should work.
Bartosz Cylwik staff commented 1 year ago
This is the simple store I used in my app.
import { createStore } from "vuex";
// Create a new store instance.
const store = createStore({
state() {
return {
notifications: [
{
id: "test",
title: "Report",
message: "Success",
status: "success",
delay: 5000,
show: true,
},
],
};
},
getters: {
notifications(state) {
return state.notifications;
},
},
mutations: {
updateNotifications(state, payload) {
state.notifications = payload;
},
},
actions: {
change(state, payload) {
state.commit("updateNotifications", payload);
},
},
});
export default store;
karluk priority commented 1 year ago
Hello Bartosz,
I tried your example as well, it throw exception. Have you try it, please? I received error message and warning as well.
Here are the warning:
[vite] connecting... client.ts:19:8
[vite] connected. client.ts:134:14
action notifications/postNotification @ 08:31:03.527 vuex.esm-bundler.js:1443:17
mutation notifications/setNotification @ 08:31:03.529 vuex.esm-bundler.js:1443:17
mutation logs/setLoader @ 08:31:03.530 vuex.esm-bundler.js:1443:17
[Vue warn]: Unhandled error during execution of watcher callback runtime-core.esm-bundler.js:41:12
[Vue warn]: Unhandled error during execution of component event handler
at
at
at
at runtime-core.esm-bundler.js:41:12
Uncaught Error: [vuex] do not mutate vuex store state outside mutation handlers.
assert vuex.esm-bundler.js:83
enableStrictMode vuex.esm-bundler.js:364
callWithErrorHandling runtime-core.esm-bundler.js:158
callWithAsyncErrorHandling runtime-core.esm-bundler.js:166
job runtime-core.esm-bundler.js:1831
triggerEffect reactivity.esm-bundler.js:373
triggerEffects reactivity.esm-bundler.js:363
trigger reactivity.esm-bundler.js:335
set reactivity.esm-bundler.js:489
0 Notification.vue:3
callWithErrorHandling runtime-core.esm-bundler.js:158
callWithAsyncErrorHandling runtime-core.esm-bundler.js:166
emit runtime-core.esm-bundler.js:669
createSetupContext/get emit/< runtime-core.esm-bundler.js:7516
hide2 MDBToast.vue:458
setTimeout handler*complete MDBToast.vue:388
addHandler MDBEventHandlers.ts:102
on MDBEventHandlers.ts:120
openToast MDBToast.vue:398
promise callback*nextTick runtime-core.esm-bundler.js:242
openToast MDBToast.vue:392
setup MDBToast.vue:445
callWithErrorHandling runtime-core.esm-bundler.js:158
callWithAsyncErrorHandling runtime-core.esm-bundler.js:166
job runtime-core.esm-bundler.js:1831
flushPreFlushCbs runtime-core.esm-bundler.js:309
updateComponentPreRender runtime-core.esm-bundler.js:5916
componentUpdateFn runtime-core.esm-bundler.js:5834
run reactivity.esm-bundler.js:178
update runtime-core.esm-bundler.js:5898
updateComponent runtime-core.esm-bundler.js:5725
processComponent runtime-core.esm-bundler.js:5660
patch runtime-core.esm-bundler.js:5124
componentUpdateFn runtime-core.esm-bundler.js:5857
run reactivity.esm-bundler.js:178
update runtime-core.esm-bundler.js:5898
callWithErrorHandling runtime-core.esm-bundler.js:158
flushJobs runtime-core.esm-bundler.js:362
flushJobs runtime-core.esm-bundler.js:372
promise callback*queueFlush runtime-core.esm-bundler.js:275
queueJob runtime-core.esm-bundler.js:269
effect runtime-core.esm-bundler.js:5894
triggerEffect reactivity.esm-bundler.js:373
triggerEffects reactivity.esm-bundler.js:363
triggerRefValue reactivity.esm-bundler.js:966
node_modules chunk-IKVZDACJ.js:1602
triggerEffect reactivity.esm-bundler.js:373
triggerEffects reactivity.esm-bundler.js:358
trigger reactivity.esm-bundler.js:335
vuex.esm-bundler.js:83:26
Bartosz Cylwik staff commented 1 year ago
I've created a fresh app from the scratch with the code I've provided and it doesn't throw errors for me.
You can try to create a fresh installed app and see whether the code works for you there: https://mdbootstrap.com/docs/vue/pro/installation/#section-vite
karluk priority commented 1 year ago
Hello Bartosz,
I created a new application based on the steps(from your website), and I added the child and parent pages as well. I am still getting same error message. If you haven't tested with vuex that is fine. please just let me know. I don't want to spent time for this. FYI: you said show up multi notifications, but how? every time, when you click the button on the parent page, you over-write the array value. please check the example.
Thank you,
karluk priority commented 1 year ago
here is the console logs
Notification.vue:3 [Vue warn]: Unhandled error during execution of watcher callback
warn2 @ chunk-5WXN7AMT.js?v=ca8d69c5:1450
logError @ chunk-5WXN7AMT.js?v=ca8d69c5:1624
handleError @ chunk-5WXN7AMT.js?v=ca8d69c5:1616
callWithErrorHandling @ chunk-5WXN7AMT.js?v=ca8d69c5:1568
callWithAsyncErrorHandling @ chunk-5WXN7AMT.js?v=ca8d69c5:1574
job @ chunk-5WXN7AMT.js?v=ca8d69c5:3241
triggerEffect @ chunk-5WXN7AMT.js?v=ca8d69c5:622
triggerEffects @ chunk-5WXN7AMT.js?v=ca8d69c5:612
trigger @ chunk-5WXN7AMT.js?v=ca8d69c5:584
set @ chunk-5WXN7AMT.js?v=ca8d69c5:742
_createBlock.onUpdate:modelValue._cache.._cache. @ Notification.vue:3
callWithErrorHandling @ chunk-5WXN7AMT.js?v=ca8d69c5:1566
callWithAsyncErrorHandling @ chunk-5WXN7AMT.js?v=ca8d69c5:1574
emit @ chunk-5WXN7AMT.js?v=ca8d69c5:2083
(anonymous) @ chunk-5WXN7AMT.js?v=ca8d69c5:8912
hide2 @ mdb-vue-ui-kit.js?v=ca8d69c5:8258
setTimeout (async)
complete @ mdb-vue-ui-kit.js?v=ca8d69c5:8201
Show 16 more frames
Show less
chunk-5WXN7AMT.js?v=ca8d69c5:1450 [Vue warn]: Unhandled error during execution of component event handler
at
at
at
at
warn2 @ chunk-5WXN7AMT.js?v=ca8d69c5:1450
logError @ chunk-5WXN7AMT.js?v=ca8d69c5:1624
handleError @ chunk-5WXN7AMT.js?v=ca8d69c5:1616
callWithErrorHandling @ chunk-5WXN7AMT.js?v=ca8d69c5:1568
callWithAsyncErrorHandling @ chunk-5WXN7AMT.js?v=ca8d69c5:1574
emit @ chunk-5WXN7AMT.js?v=ca8d69c5:2083
(anonymous) @ chunk-5WXN7AMT.js?v=ca8d69c5:8912
hide2 @ mdb-vue-ui-kit.js?v=ca8d69c5:8258
setTimeout (async)
complete @ mdb-vue-ui-kit.js?v=ca8d69c5:8201
Show 9 more frames
Show less
chunk-5WXN7AMT.js?v=ca8d69c5:1629 Uncaught Error: [vuex] do not mutate vuex store state outside mutation handlers.
at assert (vuex.js?v=ca8d69c5:57:11)
at watch.deep (vuex.js?v=ca8d69c5:291:7)
at callWithErrorHandling (chunk-5WXN7AMT.js?v=ca8d69c5:1566:18)
at callWithAsyncErrorHandling (chunk-5WXN7AMT.js?v=ca8d69c5:1574:17)
at ReactiveEffect.job [as scheduler] (chunk-5WXN7AMT.js?v=ca8d69c5:3241:9)
at triggerEffect (chunk-5WXN7AMT.js?v=ca8d69c5:622:15)
at triggerEffects (chunk-5WXN7AMT.js?v=ca8d69c5:612:7)
at trigger (chunk-5WXN7AMT.js?v=ca8d69c5:584:9)
at MutableReactiveHandler.set (chunk-5WXN7AMT.js?v=ca8d69c5:742:9)
at _createBlock.onUpdate:modelValue._cache.._cache. (Notification.vue:3:31)
Bartosz Cylwik staff commented 1 year ago
I cannot recreate your issue with the toast component. If that's possible, please upload your code to a GitHub repository & share the link here or via support@mdbootstrap.com.
We will audit the entire project, as long as it doesn't include any dependencies or custom code that could be in conflict with MDB.
karluk priority commented 1 year ago
I cannot use github or kind of repository. if it works for you, can you upload your example to github and I can check it, please?
Thank you,
Bartosz Cylwik staff commented 1 year ago
I've uploaded my example on github: https://github.com/juujisai/vue-vuex
There are 2 buttons that change the vuex state value. I've only added simple logic to the vuex, so the first one just overwrites the whole array with notifications.
Please make sure to change the Access Token inside the package.json file before running npm install.
karluk priority commented 1 year ago
I tested your example, and it works. I don't see anything is different except your store/inde.js is not typescript. any idea why? or it doesn't work with typescript, please?
Thank you,
Bartosz Cylwik staff commented 1 year ago
Hi, I've copied the store from my previous app that was not written in TS and didn't update it here. The index.js file inside the store can be a Typescript file and it still will work the same. I've updated the github repo.
Maybe some of the packages in your app are causing issues? You can check their versions, maybe some of them need to be updated.
karluk priority answered 1 year ago
Here is the child page:
<template>
<MDBToast v-model="notify.show" autohide :delay="notify.delay" appendToBody position="top-right" :stacking="true"
width="350px" :toast="notify.status" @close="removeNotification(notify.id)">
<template #title>
{{ notify.title }} - {{ notify.id }}
</template>
<template #small>
</template>
{{ notify.message }}
</MDBToast>
</template>
<script setup lang="ts">
import { MDBToast } from "mdb-vue-ui-kit";
import { INotification } from '../models/notification';
import { useStore } from "vuex";
const notify = defineProps<INotification>()
const store = useStore();
const removeNotification = async (id: string) => {
await store.dispatch('removeNotification', id)
}
</script>
karluk priority answered 1 year ago
Hello Bartosz,
In your example, you created a component, but I don't see any any parent page for using your component at all. How does it work with parent page, please?
Bartosz Cylwik staff commented 1 year ago
I cannot add another component with use of snippets, but when I've changed the value inside the parent component the Toast was triggering properly. I only used the button in my snippet to show how the opening/closing works in this case.
Were you able to implement the watcher in your application?
karluk priority answered 1 year ago
Hello Bartosz,
Or I want to show/hide the Toaster based on the computed state value. So, the Toaster will be in the page, when the state value change it will shows up until the delay time up.
Thank you,
Bartosz Cylwik staff commented 1 year ago
Hi! Using the watcher
didn't help at all? Watching for prop changes should solve the issue. If the value changes inside the same component that we used Toast in, then assigning the ref/computed value to the Toast's v-model
should also work.
Is there any chance you could show us some code here or in a snippet?
https://mdbootstrap.com/snippets
karluk priority commented 1 year ago
Basically, I have a Toaster component in my page(SPA), and based on user actions, I want to show toasters. So, each action add values to state, and the toaster watch the state value(list), and show toaster(s).
Bartosz Cylwik staff commented 1 year ago
I've prepared some code with example on how to watch for the changes of a ref value and display them on a screen. Buttons are changing the ref that we pass to the child. I used the same watcher I used in the snipped from before. Let me know if this helps.
Parent
<template>
<HelloWorld :notification="notification" />
<MDBBtn color="primary" @click="triggerAction">Trigger action</MDBBtn>
<MDBBtn
color="primary"
@click="
() => (notification = { ...notification, show: !notification.show })
"
>Toggle toast</MDBBtn
>
</template>
<script setup lang="ts">
import { MDBBtn } from "mdb-vue-ui-kit";
import HelloWorld from "../components/HelloWorld.vue";
import { ref } from "vue";
const notification = ref({
id: "test",
title: "Report",
message: "Success",
status: "success",
delay: 5000,
show: true,
});
const id = ref(0);
const triggerAction = () => {
notification.value = {
id: `test ${id.value++}`,
title: `Report ${id.value}`,
message: id.value % 2 ? "danger" : "success",
status: id.value % 2 ? "danger" : "success",
delay: 5000,
show: true,
};
};
</script>
Child
<template>
<MDBToast
v-model="notification.show"
:id="notification.id"
autohide
:delay="notification.delay"
appendToBody
position="top-right"
stacking
width="350px"
:toast="notification.status"
>
<template #title>
{{ notification.title }}
</template>
<template #small> </template>
{{ notification.message }}
</MDBToast>
</template>
<script>
import { MDBToast, MDBBtn } from "mdb-vue-ui-kit";
import { ref, onMounted, watch } from "vue";
export default {
name: "App",
components: {
MDBToast,
MDBBtn,
},
props: {
notification: {
type: Object,
default: {
id: "test",
title: "Report",
message: "Success",
status: "success",
delay: 5000,
show: true,
},
},
},
setup(props) {
const notification = ref({});
watch(
() => props.notification,
(curr) => {
notification.value = curr;
}
);
onMounted(() => {
notification.value = props.notification;
});
return {
notification,
};
},
};
</script>
karluk priority commented 1 year ago
I added parent and child pages what I have. Please check above. In the parent page you can see the loop, because I want to display multi notifications.
Thank you,
karluk priority answered 1 year ago
Hello Bartosz,
Basically, I want to show/hide my Toaster based on the property value. Not only display one time.
Thank you,
Bartosz Cylwik staff commented 1 year ago
You can use a watcher for that. Watch
the changes on the props.notification
value and then update the ref
value.
I have updated my snippet and added the watcher. The button in this snippet is beeing added on the same component so the watch doesn't trigger there (prop is not changing) but I have tested this in a new vue app and it works correctly with props aswell
https://mdbootstrap.com/snippets/vue/b-cylwik/5794125#js-tab-view
Hope that helps!
Bartosz Cylwik staff answered 1 year ago
Hello! Try assigning the prop.notification
value to the notification
ref variable after the component mounts - for example in a onMounted
hook. Something like that:
https://mdbootstrap.com/snippets/vue/b-cylwik/5794125#js-tab-view
Best Regards!
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- ForumUser: Priority
- Premium support: Yes
- Technology: MDB Vue
- MDB Version: MDB5 4.1.1
- Device: Macbook
- Browser: Firefox
- OS: OS
- Provided sample code: No
- Provided link: No