Provide / inject and this

Hi

I have a file notifications.js which contains exported functions to show a vue bootstrapper toast

function success(message) {
    this.$root.$bvToast.toast(message, {
        title: 'Success',
        autoHideDelay: 300,
        appendToast: true
      })
}

I import them and provide them in the root Vue component

new Vue({
  render: h => h(App),
  components: { App },
  provide: {
    $notify: notifications
  }
}).$mount('#app')

So I can use them in any child component like this

<template>
 ...
</template>

<script> 
export default {
  name: 'Defence',
  inject: ['$notify'],

  methods {
    save() {
       ...
       this.$notify.success('form was saved')
    }
  }
</script>

However this will not work because this is not defined inside success? How could I do this. I have temporarly solved it by having a variable in notifications.js which is set to root element with a function after it is created but it feels like an ugly hack.

Yep, this is undefined as your function is not a method of a component, it’s just a “stand-alone” function you imported from somewhere. So that is expected. welcome to the wonderful world of this :neutral_face: .

The quickest thing would probably be to make the notification module a factory function:

provide()  { // us a provide function to get proper access to `this`
  $notify: notifications(this)
}

in the module you would then have somehting like this:

export default notifications(vm) {
  return {
    success(message) {
      vm.$root.$bvToast.toast(message, {
        title: 'Success',
        autoHideDelay: 300,
        appendToast: true
      })
    }
  }
}

Can’t wait till I can forget about this with the new composition API in Vue 3.

1 Like

Thanks. I tried with a factory first but stupidly I put it on the top most vue component there this wasn’t defined and as an argument to the definition the vm wasn’t either. I think I make it a factory again and put the provide on App component there this IS defined

Yes some things about 3.0 is really worth waiting for. The timing is also good. Microsoft releases Edge Chromium in January and also is Windows 7 eol so maybe maybe the world at large finally will drop support for IE11