Search code examples
javascriptvue.jsasync-awaitpromisedexie

Awaiting Dexie query returns is promise when wrapper function is invoked from VueJS component


This most likely doesn't have anything to do with VueJS but I'm mentioning it because it's the environment that I am using.

I'm new to IndexedDB and decided to go with Dexie to remove a lot of the complexity. I've started off with creating a very simple database with a simple where query. All of Dexie's functions are return promises so inside my Vue component I have the queries wrapped inside an async/await component method.

When I go to invoke the function however, the wrapper function returns a promise rather than awaiting the Dexie query. If I console.log the query or assign the query's return value to a component variable the await works, just not when I use the function's return value directly.

This is most likely some misunderstanding that I have with promises that I'm overlooking, but why is my function returning a promise even though I'm awaiting the Dexie query?

// vue route
{
  ...
  beforeEnter: (to, from, next) => {
      const _db = new Dexie('TestDb')
      _db.version(1).stores({
        people: '++id,name,age'
      })

  Vue.prototype.$_db = _db

  next ()
}
// vue component template
...
<div>
  {{ getPeople('Pearl') }}
</div>
...
  // vue component script
  ...
  mounted () {
    this.$_db.people.add({ name: 'Mr. Krabs', age: '75' })
    this.$_db.people.add({ name: 'Pearl', age: '17' })
  },

  async getPeople (name) {
    console.log(await this.$_db.people.where({
      name: name
    }).first()
    )

    return await this.$_db.people.where({
      name: name
    }).first()
  }

Solution

  • It's because async functions always return a promise. From the MDN docs:

    Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.

    Statements that you use await on don't do this:

    Await expressions suspend progress through an async function... The resolved value of the promise is treated as the return value of the await expression

    So when you log such a statement, you see the value. But if you return that value and log it, it will have been wrapped in that implicit promise.