MDBToast is not show up


Topic: MDBToast is not show up

karluk pro premium priority asked 6 months 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);


Bartosz Cylwik staff answered 6 months 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!


karluk pro premium priority answered 6 months 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 5 months 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!


karluk pro premium priority answered 5 months 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 5 months 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 pro premium priority commented 5 months 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 5 months 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 pro premium priority commented 5 months 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 pro premium priority answered 5 months 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 5 months 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 pro premium priority answered 5 months 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 pro premium priority answered 5 months 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 5 months 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 pro premium priority commented 5 months 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 5 months 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 pro premium priority commented 5 months 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 pro premium priority commented 5 months 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 5 months ago

You can find example with vuex in my comment above.


karluk pro premium priority commented 5 months 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 5 months 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 5 months 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 pro premium priority commented 5 months 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 5 months 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 pro premium priority commented 5 months 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 pro premium priority commented 5 months 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 5 months 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 pro premium priority commented 5 months 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 5 months 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 pro premium priority commented 4 months 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 4 months 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.


Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue
  • User: Pro
  • 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
Tags