'Call mixin function from asyncData() method of the page component with Nuxt.js

Can I call mixin function from asyncData() method of the page component with Nuxt.js?

My code:

<template>
  ...
</template>
<script>
   import api from "@/plugins/api/api.js"

   ...

   export default {

      ...

      async asyncData(context) {
          ...
          context.apiMethodName()
          ...
      }

      ...
   }

   ...
</script>

api.js

import Vue from 'vue'
import API from '@/assets/js/api'

Vue.mixin({
  methods: {
    apiMethodName() { ... }
  }
})


Solution 1:[1]

You cant call vue methods from withing asyncData, because asyncData executed before vue have an instance.

You can extract method into simple js function and call it both in asyncData and your vue method, but keep in mind that in asyncData you wont be able to access vue instance properties and other methods

Solution 2:[2]

You can inject mixin into app, see https://nuxtjs.org/guide/plugins#inject-in-root-amp-context

Solution 3:[3]

I see it is quite late for the answer, but it is possible.

template.vue

<template>
...
</template>
<script>
  import api from "~/mixins/api/api"
  ...

  export default {
    ...

    async asyncData({context}) {
      ...
      // You don't need to use context
      // You have to use "api" like this:
      const collection = await api.methods.apiMethodName()
      ...

      // bear in mind you should return data from this function
      return {
        collection,
        ...
      }
    }
    ...
  }
  ...
</script>

~/mixins/api/api.js

const api = {
  ...
  methods: {
    async apiMethodName() {
      ...
      // better use here try / catch or Promise with then / catch
      const data = await do_something()
      ...

      return data
    }
    ...
  }
  ...
}

export api

A similar approach was tested with stack VueJS + NuxtJS and it is working on the live website https://elfinforce.com.

Solution 4:[4]

you can access global mixin methods like this:

app.router.app.gloablMethod()

so simple!

Solution 5:[5]

You need to abandon using mixins and inject your methods instead.

First; Replace your mixin method to be

export default ({ app }, inject) => {
  inject('apiMethodName', () => {
    return 'some data!';
  })
}

Then, inside asyncData() method, call apiMethodName() function like so

async asyncData(context) {
  context.app.$apiMethodName();
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Aldarund
Solution 2
Solution 3 Igor Popov
Solution 4 amirhosein armantaheri
Solution 5 Muhammad Reda