Skip to content

Instantly share code, notes, and snippets.

@paulrose
Forked from guanzo/Vue stuff.md
Created May 19, 2020 04:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paulrose/45c801561c921cd3e5c63ed999f2dc93 to your computer and use it in GitHub Desktop.
Save paulrose/45c801561c921cd3e5c63ed999f2dc93 to your computer and use it in GitHub Desktop.

Async calls

<template>
<p v-if="isLoading">
  Loading...
  {{ myData.if.you.try.to.access.properties.here.it.will.error }}
</p>
<p v-else>
  {{ myData.you.can.access.properties.now.that.myData.is.loaded }}
  <MyComponent :data="myData.you.can.pass.data.to.components.now"/>
</p>
</template>

<script>
export default {
  data: () => ({
    isLoading: false,
    myData: null,
  }),
  async created () {
    try {
      this.isLoading = true
      await this.fetchData()
      // Make sure to handle any errors :)
    } finally {
      this.isLoading = false
    }
  },
  methods: {
    async fetchData () {
      const res = await axios.get('/api/myData')
      this.myData = res.data.myData
    }
  }
}
</script>

WTF is "this"??

Save yourself hours of pain, and learn how "this" works.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

<script>
export default {
  data: vm => ({
    badData: this.badMethod(), // 'this' = window
    goodData: vm.goodMethod()  // 'vm' = vue component
  }),
  computed: {
    badComputed: () => this.badData, // 'this' = window
    goodComputed: vm => vm.goodData, // 'vm' = vue component
    goodComputed2 () {
      console.log(this) // vue component
    }
    goodComputed3: function () {
      console.log(this) // vue component
    }
  },
  methods: {
    badMethod: () => {
      console.log(this) // window
    },
    goodMethod () {
      console.log(this) // vue component
    },
    goodMethod2: function () {
      console.log(this) // vue component
    },
    // Function doesn't reference "this", so an arrow function is fine here.
    doesntMatter: () => 1 + 1
  },
  created () {
    // BAD
    // The "function" keyword affects the value of "this".
    axios.get().then(function (response) {
      console.log(this) // window
    })

    // GOOD
    // An arrow function causes the function to inherit the "this" value from the
    // parent scope, in this case, the scope of the created() function.
    axios.get().then(response => {
      console.log(this) // vue component
    })

    // GOOD
    // Prefer arrow functions, but saving the value of "this" in a higher scope will also work.
    const self = this
    axios.get().then(function (response) {
      console.log(this) // window
      console.log(self) // vue component
    })

    // BAD
    // Obviously this doesn't just apply to axios callbacks, it applies to any callback.
    setTimeout(function () {
      console.log(this) // window
    }, 0)

    // GOOD
    setTimeout(() => {
      console.log(this) // vue component
    }, 0)
  
    // You can avoid some of these "gotchas" with async/await, refer to the
    // fetchData() method in the earlier "Async calls" section.
  },
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment