1

I am building a web app with nuxt.

here's simplified code:

pages/index.vue

data() {
 return {
  item: {name:'', department: '', testField: '',},
 }
}
async asyncData() {
  const result = call some API

  const dataToInitialize = {
   name: result.username,
   department: result.department,
   testField: //want to assign computed value
  }
  return {item: dataToInitialize}
}

Inside asyncData, I call API and assign value to dataToInitialize. dataToInitialize has testField field, and I want to assign some computed value based on username and department. (for example, 'a' if name starts with 'a' and department is 'management'..etc there's more complicated logic in real scenario)

I have tried to use computed property , but I realized that asyncData cannnot access computed.

Does anyone know how to solve this? Any help would be appreciated!

=======

not sure if it's right way, but I solved the issue by setting 'testfield' inside created.

created() {
    this.item.testField = this.someMethod(this.item);
},
kissu
  • 40,416
  • 14
  • 65
  • 133
amu03
  • 129
  • 11
  • `created` should be called after `asyncData`, is it working as expected? – kissu Jul 02 '21 at 01:30
  • it's working as expected. I first initialize data with asyncData, then overwrites testField field inside created so the data was correctly displayed. I will try the method that you suggested.(using fetch) @kissu – amu03 Jul 02 '21 at 02:57

2 Answers2

1

Looking at the Nuxt lifecyle, you can see that asyncData is called before even a Vue instance is mounted on your page.
Meanwhile, fetch() hook is called after. This is non-blocking but more flexible in a lot of ways.

An alternative using fetch() would look like this

<script>
export default {
  data() {
    return {
      staticVariable: 'google',
    }
  },
  async fetch() {
    await this.$axios(this.computedVariable)
  },
  computed: {
    computedVariable() {
      return `www.${this.staticVariable}.com`
    },
  },
}
</script>

Another alternative, would be to use URL query string or params, thanks to Vue-router and use those to build your API call (in an asyncData hook).
Here is an example on how to achieve this: https://stackoverflow.com/a/68112290/8816585


EDIT after comment question
You can totally use a computed inside of a fetch() hook indeed. Here is an example on how to achieve this

<script>
export default {
  data() {
    return {
      test: 'test',
    }
  },
  async fetch() {
    const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${this.nice}`)
    console.log(await response.json())
  },
  computed: {
    nice() {
      return this.test + 'wow!'
    },
  },
}
</script>
kissu
  • 40,416
  • 14
  • 65
  • 133
  • I tried using fetch() as you suggested and I could see that I can use computed value inside fetch. One problem though. Inside fetch, I replaced this line`return {item: dataToInitialize}`, with `this.item=dataToInitialize` but `this.item` that's supposed to displayed on the page is blank. I use component and pass `this.item` as a prop to this child component. Is that because child component is created and mounted before fetch is done? – amu03 Jul 02 '21 at 04:43
  • I've edited my answer, even tho I'm not sure of you do want exactly. Also, this link may maybe help, to see how the whole thing is mounted: https://stackoverflow.com/a/44319825/8816585 And here is Nuxt's lifecycle: https://nuxtjs.org/docs/2.x/concepts/nuxt-lifecycle @amu03 – kissu Jul 05 '21 at 15:10
0

I found that destructuring fetch({}) causes issues with accessing this inside fetch scope ->

async fetch({ store, $anyOtherGlobalVar }){ 
store.dispatch... 
// destructuring approach changes the scope of the function and `this` does not have access to data, computed and e.t.c
}

If you want to access this scope for example this.data, avoid destructuring and access everything through this.

async fetch() {
 this.$store...
 this.data...
}
Jeronimas
  • 64
  • 6