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

5

5

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() { ... }
  }
})
Hebel answered 18/3, 2019 at 10:11 Comment(0)
C
8

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

Calore answered 19/3, 2019 at 9:22 Comment(7)
You CAN call a method from asyncData. See my answer.Thighbone
@IgorPopov not true. You are not calling method of component from asyncData. You just calling external function without access to component this.Calore
What makes you unable to write asyncData in a page component? However according to the documentation while running asyncData function Vue instance is not yet created. So if we are talking about "this" - it doesn't exist yet. And you forget about the purpose of asyncData: this is a hook that can only be placed on page components, it blocks route navigation until it is resolved and must return data.Thighbone
Meanwhile, the key question from the author is: Can I call mixin function from asyncData? And the answer is YES, you can. Author did not ask to call a "method of component", but "mixin function". In the first comment, I made a mistake. I meant to call the function from mixin from a separate file.Thighbone
@IgorPopov the question was about calling mixin function from asyncData. Thats it. Your solution is just call external function which you obv can do from anywhere and it has nothing to do with quesiton. What you propose isnt calling mixin function. Mixin is a specific thing is vue, not some random external function in other file.Calore
Literally, a mixin is a JS object which can contain instance options like normal instance objects. During the creation of Vue instance, it merged against the eventual options using the certain option merging logic. But before creating Vue instance being imported mixin is simply yet another random external JS Object. And while it is still in a Vue life cycle it is acceptable. You can argue for whole your life, or use the working approach posted by me :)Thighbone
@IgorPopov lol, ofc your approach working. its essentialy same as writing all code inside asyncData but just moving it outside into function. But again its nothing to do with question that op asked. In mixin you have access to instance in your approach noCalore
T
2

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.

Thighbone answered 19/2, 2022 at 1:26 Comment(0)
N
0

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

Naze answered 12/3, 2020 at 9:54 Comment(1)
You don't need any injection. You CAN call a method from asyncData. See my answer.Thighbone
I
0

you can access global mixin methods like this:

app.router.app.gloablMethod()

so simple!

Increment answered 27/4, 2022 at 15:31 Comment(0)
F
-1

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();
})
Foreconscious answered 28/7, 2021 at 12:30 Comment(1)
That's not true. It is possible.Thighbone

© 2022 - 2024 — McMap. All rights reserved.