How to use Quasar plugins (Notify, Loading) inside Vuex modules?



  • I’m trying to initiate/stop ‘Loading’ or display ‘Notify’ messages right in Vuex upon updating certain properties or upon receiving certain responses from axios rather than repeat the same code in multiple components. What’s the correct way to import these Quasar plugins in Vuex?

    Thank you.



  • @mas If you are using axios, you can do it in your axios boot file, then use axios request/response interceptors. Let’s see what have you tried first…



  • @mas
    To use Notify in Vuex with Axios, I’ve implemented as follows

    import { Notify } from 'quasar'
    
    ...
    
    
    export const postAction = (context) => {
      Vue.prototype.$axios.post(process.env.API + 'xxxx/' + 'xxxx/', {
        id: context.state.selectedPersonId,
        title: context.state.personSelectedAllData.person.title,
        ....
        
          })
        .then(function (response) {
          if (response.status === 200) {
              Notify.create({
                type: 'positive',
                color: 'positive',
                timeout: 1000,
                position: 'center',
                message: 'Yeah. Data saved. Great Job!'
              })
          }
        })
        .catch(function (error) {
          console.log(error)
            Notify.create({
              type: 'warning',
              color: 'warning',
              timeout: 1000,
              position: 'center',
              message: 'Uups. Something went wrong!'
            })
        })
    }```


  • This post is deleted!


  • @stukki, thank you - exactly what I needed!



  • @mas you could do it simpler like this:

    export function myAPI (context, data) {
      this._vm.$q.loading.show()
      this._vm.$axios.post(`my-API-path`, data).then(response => {
        this._vm.$q.loading.hide()
        this._vm.$q.notify({
          message: 'Your message',
          color: 'positive'
        }
      }).catch(error => {
        this._vm.$q.loading.hide()
        this._vm.$q.notify({
          message: 'Your error',
          color: 'negative'
        }  
      })
    }
    


  • @mas You may even return the $axios promise and catch it at the component level:

    export function myAPI (context, data) {
      this._vm.$q.loading.show()
      return this._vm.$axios.post(`my-API-path`, data)
    }
    

    Then in your component

    import { mapActions } from 'vuex'
    export default {
      methods: {
        ...mapActions(['myAPI'])
        // Or if you're action is in a module
        ...mapActions('you-module', ['myAPI'])
      },
      hitMyAPI () {
        this.myAPI().then(response => {
          this.$q.loading.hide()
          this.$q.notify({
            message: 'Your message',
            color: 'positive'
          }
        }).catch(error => {
          this.$q.loading.hide()
          this.$q.notify({
            message: 'Your error',
            color: 'negative'
          }
        })
      }
    }
    


  • @danielcoliev , thank you for suggestion. But which of the above options would be more preferable for performance and maybe other reasons?



  • @mas For performance I really don’t know, I don’t think it really makes a significant difference, in my case I use to catch the axios promise in the action when is an action that I use only one time or the then/catch proccess is the same wherever I use it, but I have times where I have a same action that I use in different places, and depending where I use it the then/catch proccess is different, then I handle it at the component level. For example:

    I have an endpoint in my API where I retrieve notifications, but I show them on different places and devices (cordova, pwa, etc…) and I handle the then/catch different based on where the notifications are shown and which device is being shown on. For that I prefer to handle them at the component level and not crowd my actions file. Hope it helps!



  • if you want to handle every request/response, better do it in your axios boot file via interceptors like i stated above, boot file has access to the store too.
    example:

    import { Loading, QSpinnerGears, Notify } from 'quasar'
    import axios from 'axios'
    export default ({ Vue, store }) => {
    ...
      // add a request interceptor
      axios.interceptors.request.use(config => {
        // change some state in your store here
        // Do something before request is sent
        Loading.show({
          spinner: QSpinnerGears,
          // other props
        })
        return config
      }, error => {
        // Do something with request error
        Notify.create(...)
        Loading.hide()
        return Promise.reject(error)
      })
    // Add a response interceptor
      axios.interceptors.response.use(response => {
        // Do something with response data
        // call some store functions etc..
        Loading.hide()
        return response
      }, error => {
       Notify.create(...)
       Loading.hide()
        // Do something with response error       
        return Promise.reject(error)
      })
      Vue.prototype.$axios = axios
    }
    

    https://github.com/axios/axios#interceptors



  • @metalsadman, @danielcoliev , thank you! It took a while to understand some things properly)


Log in to reply