DEV Community

loading...
Cover image for Async lifeCycle hooks may cause props to be undefined

Async lifeCycle hooks may cause props to be undefined

Ahmed Yagoub
Developer, bootcamp grad, Engineer
Updated on ・2 min read

Introduction

Have you ever passed down props from parent to a child component in vue only to realize that the prop isn't yet available but showing undefined instead?

Well, one possibility is the presence of async code in lifecycle hooks

Example

// parent.js
<script>
  import Child from './child'
  export default{
    data() {
      return {
        prop: undefined,
      }
    }
    async created() {
      this.prop = await this.$store.dispatch('getProp')
    }
  }
</script>
<template>
  <Child
    :prop=prop
  />
</template>
Enter fullscreen mode Exit fullscreen mode
// child.js
<script>
  export default{
    props: ['prop'],
    created() {
      console.log(this.prop)
    }
  }
</script>
<template>
   ...
</template>
Enter fullscreen mode Exit fullscreen mode

When we pass props from parent components to children, props are available by the time the created hook runs since the parent created hook runs before the child created hook. (The opposite for mounted hook).

However, in cases like the example above console.log(this.prop) will output undefined and that is because the lifecycle hooks themselves are synchronous even if they include async code inside of them.

In the example above, the created hook in the child component will be called immediately after the created hook in the parent component is called. It will not wait for the code inside of it to finish.

In fact, console.log(this.prop) might still result in undefined even if it is called in mounted hook instead. Although, the hooks run in order, the code inside them could finish at a later time.

Solution

I have no idea of when the prop is available in the child component, so my proposed solution is to watch it, and run that watcher only once

 watch: {
  prop(new, old) {
      if (old === undefined && new !== undefined) {
        console.log(this.prop)
      }
    },
  },
Enter fullscreen mode Exit fullscreen mode

now, the output would give you the prop.

Discussion (0)