Notify Plugin onDismiss



  • I there anyhow a possibility to get always the last mesage posted by this.$q.notify by the ‘onDismiss’ handler?

    <template>
      <div id="q-app">
        <router-view />
      </div>
    </template>
    <script>
    export default {
      name: 'App',
      created () {
        this.$q.notify.setDefaults({
          onDismiss: () => this.callNotify()
        })
      },
      methods: {
        callNotify () {
          // post here always the last notify message/caption
        }
      }
    }
    </script>
    

    a look into the sources depicts that unfortunately onDismiss doesn’t have a param.

      remove (notif) {
          clearTimeout(notif.meta.timer)
    
          const index = this.notifs[notif.position].indexOf(notif)
          if (index !== -1) {
            if (notif.group !== void 0) {
              delete groups[notif.meta.group]
            }
    
            const el = this.$refs[`notif_${notif.meta.uid}`]
    
            if (el) {
              const { width, height } = getComputedStyle(el)
    
              el.style.left = `${el.offsetLeft}px`
              el.style.width = width
              el.style.height = height
            }
    
            this.notifs[notif.position].splice(index, 1)
    
            this.$forceUpdate()
    
            if (typeof notif.onDismiss === 'function') {
              notif.onDismiss()
            }
          }
        }
      },
    
    

    any chance to extend it? (because it is a plugin, not a compoment)



  • @donsherman This is completely untested, but try something like this

    // src/boot/myNotify.js (remember to add to quasar.conf.js)
    import { Notify } from 'quasar'
    
    export default ({ Vue }) => {
      let lastMessage = ''
      Vue.prototype.$myNotify = params => {
        if(typeof params === 'string') {
          params = { message: params } // support basic string usage
        }
        lastMessage  = params.message
        const oldOnDismiss = params.onDismiss
    
        Notify.create({
          ...params,
          onDismiss: () => {
            if(typeof oldOnDismiss  == 'function') {
              oldOnDismiss(lastMessage)
            }
          }
        })
      }
    }    
    

    Then use it like this in some component:

    export default {
      created () {
        this.$myNotify({
          message: 'hello',
          onDismiss: this.callNotify
        })
      },
      methods: {
        callNotify (lastMessage) {
          console.log(lastMessage)
        }
      }
    }
    

    It might need some tweaking, and might not be exactly what you need, but is a start



  • Thanks, but I must confess, that I don’t understand your example at all, so that I’ll be not able to tweak it right.
    How does “myNotify” inhertis all the things of Notify i.e.?



  • @donsherman $myNotify is basically a wrapper around Notify that passes all arguments, and adds the onDismiss function.

    This part “extends” the parameters you pass via the spread operator.

        Notify.create({
          ...params,
          onDismiss: () => {
            if(typeof oldOnDismiss  == 'function') {
              oldOnDismiss(lastMessage)
            }
          }
        })
    

    So basically, if you call

    $myNotify({ 
      type: 'positive',
      message: `This is a "positive" type notification.`
    })
    

    It is equivalent to

    $q.notify({ 
      type: 'positive',
      message: `This is a "positive" type notification.`,
      onDismiss: () => {
        if(typeof oldOnDismiss  == 'function') {
          oldOnDismiss(lastMessage)
        }
      }
    })
    

    What the rest of the boot file does, is simply store the last message in a variable. Where you might need to tweak the code, is that I notice you might need the lastMessage variable in App.vue. I’m not sure your end goal, so I’m not positive if the code needs to change. But if you do need this info elsewhere in the app, I can help tweak it with you.

    P.S. hit the reply button or @ me, since otherwise I didn’t get a notification of your response.



  • @beets Thanks again.
    My goal is to log all notify messages in a Sessionstorage and to list them all when user clicks a certain button on the main page.
    I want to wrap them with an additional timestamp and maybe also the caption (if there was one set)

    So with your apporach, it doesn’t seem to be somehow necessary to put stuff into App.vue.
    Your Notify boot file will be sufficient for that (as far as I may understood it)

    I will try your suggestions within the next days. One little imperfection is, to refactor all my $q.notifes in the sources with $myNotify
    But Ok, that’s nothing bad 😉

    Btw and OT: How Can I format here code tokens in that red/filled style?



  • @beets got it now somehow.
    This boot file works for me :

    import { SessionStorage } from "quasar";
    import Vue from "vue";
    import { date, Notify } from "quasar";
    
    export default ({ Vue }) => {
      let lastMessage = "",
        lastCaption = "",
        keyInc = 0;
      SessionStorage.clear();
      
      const logNotify = (c, m) => {
        let stamp =
          "[" + date.formatDate(Date.now(), "HH:mm:ss") + "] " + c + ":" + m;
        SessionStorage.set("notifyKey" + keyInc++, stamp);
        console.log(SessionStorage.getAll());
      };
    
      Vue.prototype.$logNotify = params => {
        if (typeof params === "string") {
          params = { message: params }; // support basic string usage
        }
        lastCaption = params.caption ? params.caption : "";
        lastMessage = params.message;
        const oldOnDismiss = logNotify;
    
        Notify.create({
          ...params,
          onDismiss: () => {
            if (typeof oldOnDismiss == "function") {
              oldOnDismiss(lastCaption, lastMessage);
            }
          }
        });
      };
    };
    

    Thanks a lot



  • @donsherman Glad you got it working.

    So with your apporach, it doesn’t seem to be somehow necessary to put stuff into App.vue.

    Your Notify boot file will be sufficient for that (as far as I may understood it)

    That’s correct, if you’re just pushing into session storage, a boot file is perfect for that. You could also push into vuex, etc.

    One note on your final code. This part:

        const oldOnDismiss = logNotify;
    
        Notify.create({
          ...params,
          onDismiss: () => {
            if (typeof oldOnDismiss == "function") {
              oldOnDismiss(lastCaption, lastMessage);
            }
          }
        });
    

    My original intention was to store a reference to any onDismiss function passed into $myNotify and call that. Storing a reference was necessary since the boot file overrides that callback. In your example, you can simplify it to:

        Notify.create({
          ...params,
          onDismiss: () => {
            logNotify(lastCaption, lastMessage);
          }
        });
    

    Btw and OT: How Can I format here code tokens in that red/filled style?

    You can surround the token in single backticks like: `example`



  • @beets thx again for your hints 😉
    Here’s my final release:

    import Vue from "vue";
    import { date, Notify, SessionStorage } from "quasar";
    
    export default ({ Vue }) => {
      let lastMessage = "",
        lastCaption = "",
        keyInc = 0;
      SessionStorage.clear();
    
      const logNotify = (c, m) => {
        let stamp = `[${date.formatDate(Date.now(),"DD-MMM-YYYY HH:mm:ss" )}] ${c} : ${m}`;
        SessionStorage.set(`notifyKey${keyInc++}`, stamp);
        //console.log(SessionStorage.getAll());
      };
    
      Vue.prototype.$logNotify = params => {
        if (typeof params === "string") {
          params = { message: params }; // support basic string usage
        }
        lastCaption = params.caption ? params.caption : "";
        lastMessage = params.message;
    
        Notify.create({
          ...params,
          onDismiss: () => {
            logNotify(lastCaption, lastMessage);
          }
        });
      };
    };
    


  • @donsherman Great! One last thing I’ll explain, just so you understand the whole piece of the code:

        if (typeof params === "string") {
          params = { message: params }; // support basic string usage
        }
    

    This part of the code is there since you can call notify two ways: $q.notify('hello') and $q.notify({ message: 'hello' }). So I wanted to make sure $myNotify worked the same way. Basically just checks if you passed a string and converts it to an object. If you never use the basic string usage, you could just remove those lines, but it doesn’t hurt to keep them there, as long as you understand why it’s in the code.

    Glad it all worked out!


Log in to reply