Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In nuxt, $toast is not available in context inside another plugins like axios #19

Open
jralison opened this issue Aug 5, 2019 · 9 comments

Comments

@jralison
Copy link

jralison commented Aug 5, 2019

I have the $toast property working just fine in my components and in the store, but when I try to call it from a plugin (axios in this case), the property isn't available.

I tried this in ~/plugins/vuetify-toast-snackbar.js:

import Vue from 'vue'
import VuetifyToast from 'vuetify-toast-snackbar'

Vue.use(VuetifyToast)

export default ({ app }, inject) => {
  inject('toast', Vue.prototype.$toast)
}

And in ~/plugins/axios.js, with:

export default function ({ $axios, $toast }) {
  $axios.onError((error) => {
    if (process.client && !!$toast) {
      if (error.response) {
        $toast.error(`${error.response.status} ${error.response.statusText}`)
      } else if (error.request) {
        $toast.error('A aplicação não foi capaz de completar a requisição.')
      } else {
        $toast.error(`Algo deu errado! ${error.message}`)
      }
    }
  })
}

neither app.$toast nor ctx.$toast is available.

Can you help me to identify what might be wrong in my code?
All the workaround I have tried up to here are being unsuccessful.

@eolant
Copy link
Owner

eolant commented Aug 5, 2019

@jralison yes, that is an interesting one.
I've spent some time to figure out how to do it and here is the workaround

You should be able to access Vue.prototype.$toast. It will definitely work with Vuetify 1.5. I'll take a look at Nuxt.js + Vuetify 2 later.

@jralison
Copy link
Author

jralison commented Aug 6, 2019

@eolant I think I found out what was my mistake.

$toast property is not available in the context object at first run of the plugin script, but it is available in ctx.app later on. So, when using object destructuring in the function argument { $axios, $toast } to extract the $toast reference, I ended up assigning $toast to a undefined.

Thus, I have to extract the app property and later then I can use that variable to access the $toast callables.

Also, instead of combining ctx.$toast = Vue.prototype.$toast and inject('toast', Vue.prototype.$toast) during vuetify-toast-snackbar initialization, I can stand with the latter statement and that's enough to make it work.

Btw, I am currently using Vuetify 2.0.4 and Nuxt 2.8.1.

Thank you for this awesome helper library and for your support.

@eolant
Copy link
Owner

eolant commented Aug 6, 2019

@jralison that's great, I didn't have a chance to look at Vuetify 2 just yet, but I can say that $toast doesn't seem to be available anywhere on Vuetify 1.5 and Nuxt 2.4 and the workaround I suggested is the only way to access it.

I'll leave this open for now and maybe look at updating Readme with all of this information.

@ChrisKader
Copy link

Below is my configuration. I am using electron nuxt with no issues.

  • plugins/snackstack.js
import Vue from 'vue'
import VuetifyToast from 'vuetify-toast-snackbar'
 
Vue.use(VuetifyToast, {
    x: 'right', // default
    y: 'bottom', // default
    color: 'info', // default
    icon: 'info',
    iconColor: '', // default
    classes: [
        'body-2'
    ],
    timeout: 3000, // default
    dismissable: true, // default
    multiLine: false, // default
    vertical: false, // default
    queueable: false, // default
    showClose: false, // default
    closeText: '', // default
    closeIcon: 'close', // default
    closeColor: '', // default
    slot: [], //default
    shorts: {
        custom: {
            color: 'purple'
        }
    },
    property: '$toast' // default
})
  • plugins/veutify.js
import('roboto-fontface/css/roboto/roboto-fontface.css');
import('roboto-fontface/fonts/roboto/Roboto-Thin.woff2') //100
import('roboto-fontface/fonts/roboto/Roboto-Light.woff2') //300
import('roboto-fontface/fonts/roboto/Roboto-Regular.woff2') //400
import('roboto-fontface/fonts/roboto/Roboto-Medium.woff2') //500
import('roboto-fontface/fonts/roboto/Roboto-Bold.woff2') //700
import('roboto-fontface/fonts/roboto/Roboto-Black.woff2') //900
import Vue from 'vue'
import Vuetify, { VSnackbar, VBtn, VIcon } from 'vuetify/lib'
import VuetifyToast from 'vuetify-toast-snackbar'
 
Vue.use(Vuetify, {
  components: {
    VSnackbar,
    VBtn,
    VIcon
  }
})
Vue.use(VuetifyToast)
  • nuxt.config.js
module.exports = {
  mode: 'spa', // or 'universal'
  head: {
    title: 'StackThemSnacks'
  },
  loading: false,
  plugins: [
    {ssr: true, src: '@/plugins/icons.js'},
    {ssr: true, src: '@/plugins/snackstack.js'}
    
  ],
  modules: [
    '@nuxt/typescript-build',
    '@nuxtjs/vuetify',
  ],
          vuetify: {
            theme: {
              themes: {
                light: {
                  primary: '#1867c0',
                  secondary: '#b0bec5',
                  accent: '#8c9eff',
                  error: '#b71c1c',
                },
              },
            }
          }
};

@ChrisKader
Copy link

My goal over the next few days is to get this connected to Vuex so that I can do a commit to an array and produce an alert.

@eolant
Copy link
Owner

eolant commented Sep 26, 2019

@ChrisKader you can use:

import Vue from 'vue'
Vue.prototype.$toast('Message from the store')

@paulrad
Copy link

paulrad commented Oct 3, 2019

My fix in plugins/toast.js :

import Vue from 'vue'
import VuetifyToast from 'vuetify-toast-snackbar'

Vue.use(VuetifyToast, {
  timeout: 5000,
  queuable: true
})

export default (context, inject) => {
  inject('toast', Vue.prototype.$toast)
}

@allocenx
Copy link

This does not work either "Cannot read property '$options'". No matter what. Seems pointless...

@easy-ms
Copy link

easy-ms commented Oct 24, 2021

I'm using toast with own plugin to handle errors from API. Here's my solution that work.

plugins/axios.js

export default function ({ $axios, $toast }) {
  $axios.onError((error) => {
    $toast.error(error.response.data)
  })
}

nuxt.config.js

...
plugins: ['~/plugins/axios.js'],

modules: [
    '@nuxtjs/axios',
    '@nuxtjs/auth-next',
    '@nuxtjs/toast',
], ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants