bootstrap-vue: Cannot access $bvToast in Nuxt plugin
Describe the bug
I want to display API errors as toast messages. I have to use a Nuxt plugin to work with Axios error interceptors. The plugin has access to the Vue instance app from the Nuxt context. However, the app instance is missing the $bvToast injection. So calls like app.$bvToast.toast('some toast message') fail.
Steps to reproduce the bug
- Create a Nuxt plugin called
/plugins/axios-toast.js
export default function ({ $axios, app }) {
$axios.onError(error => {
app.$bvToast.toast(error)
})
}
- Reference the plugin in
nuxt.config.js
plugins: [
'~plugins/axios-toast.js'
],
- Intentionally trigger an invalid route
<b-button @click="$axios.$get('badroute')">Do it</b-button>
- Observe the error in the browser
TypeError: Cannot read property ‘toast’ of undefined
Expected behavior
The Vue instance app in the Nuxt plugin context should have the $bvToast injected.
Versions
Libraries:
- BootstrapVue: 2.4.1
- Bootstrap: 4.4.1
- Nuxt 2.11.0
- Nuxt Axios 5.9.5
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 1
- Comments: 16 (9 by maintainers)
I used this:
$nuxt.$bvToast.toast(error)in my Axios interceptor and works fine!In case someone is using Client-Side Rendering only, this issue can be solved by using
window.$nuxtFor e.g.
it works:
There actually was a limited debugging offered for errors in plugins and my code had an error in it. Due to this it didn’t work when I tried. It looks like you can do this via $nuxt available in the plugins:
The
appkey on the nuxt context object is not the$rootVue instance, but rather it is the options object used to define the app: https://nuxtjs.org/api/context#universal-keysIf you were to check
context.app._isVueyou will find that_isVueis undefined ascontet.appis not an actual Vue instance, and that there are no properties like$root, or$parent, etc, defined on it.$bvToastrequires a Vue instance to work.In your plugin, you could try:
But note that this will be a singleton Vue instance that doesn’t share the same
$rootas your app, so events will not be emitted onto the app$rootHow are you accessing $nuxt? This is in context with ~/plugin/axios.js
I wouldn’t instantiate a new copy of the instantiated app, as that would double your memory footprint and potentially have adverse affects with your app.