Javascript async function returns [object Promise]

user4565857 picture user4565857 · Jun 8, 2019 · Viewed 10.6k times · Source

Async function returns [object Promise] but desired behavior is returning real value. I can get the value from console.log.

I guess it is a expected behavior of the function but I have no idea to how to fix my code.

This is in vue.js code using electron-vue and NeDB.

<template>
  <div>
    {{ testNedb3('NDId6sekw6VYLmnc')  //this is a test by adding specific id }}
  </div>
</template>

<script>
import Promise from 'bluebird'
export default {
  methods: {
    dbFindAsync2: function (db, opt) {
      return new Promise(function (resolve, reject) {
        db.find(opt, function (err, doc) {
          if (err) {
            reject(err)
          } else {
            resolve(doc)
          }
        })
      })
    },
    testNedb3: async function (id) {
      const flattenMemAsync = function (arr) {
        return new Promise(function (resolve) {
          Array.prototype.concat.apply(
            [],
            arr.map(function (arr) {
              resolve(arr.members)
            })
          )
        })
      }
      const filterByNameIdAsnc = function (arr) {
        return new Promise(function (resolve) {
          const result = arr.filter(function (member) {
            return member.nameId === id
          })
          resolve(result)
        })
      }
      this.dbFindAsync2(
        this.$db, { 'members.nameId': id }, { 'members': 1, _id: 0 }
      ).then(function (res) {
        const docs = res
        flattenMemAsync(docs).then(function (res) {
          const flatMembers = res
          filterByNameIdAsnc(flatMembers).then(function (res) {
            console.log('result', res)
            console.log('result_firstname', res[0].firstName)
            return res
          })
        })
      })
    },

this.$db is getting data from NeDB and the data is two-dimensional array, so I am trying to flat the array by flattenMemAsync and remove unexpected data by filterByNameIdAsnc.

console.log('result', res) returns array and console.log('result_firstname', res[0].firstName) returns string.

I have changed calling code from {{ testNedb3('NDId6sekw6VYLmnc') }} to {{ {{ testNedb3('NDId6sekw6VYLmnc').then(value => {return value}) }} but the result is same.

Also changed to {{ await testNedb3('NDId6sekw6VYLmnc').then(value => {return value}) }} but I got error "Parsing error: Cannot use keyword 'await' outside an async function.".

Any comment can help me. Thank you.

Answer

filipe picture filipe · Jun 9, 2019

Don't call an async method within a view.

When you mark the method as async it will return a promise, so, its pointless to return a promise and mark it as async at same time.

You should await the async method or promise from created or some other suitable lifecycle hook and save the result in component’s data, then render that data.

Also, take a look at vue-promised plugin.