0

I'm wrapping my dynamoDB function into another function and I'm having issues with returning it to the "item" const. What I'm missing here?

Works:

    const params = {
      TableName: table,
      Key: {
        id: id
      },
    };

    dynamoDb.get(params, (error, result) => {
      if (error) {
        console.error(error);
        callback(null, {
          statusCode: error.statusCode || 501,
          body: 'Couldn\'t fetch the item.',
        });
        return;
      }

      const item = result.Item
    })

Doesn't work (returns undefinied):

  const getFromDb = () => {
    const params = {
      TableName: table,
      Key: {
        id: id
      },
    };

    dynamoDb.get(params, (error, result) => {
      if (error) {
        console.error(error);
        callback(null, {
          statusCode: error.statusCode || 501,
          body: 'Couldn\'t fetch the item.',
        });
        return;
      }

      return result.Item
    })
  }

  // Get from db
  const item = getFromDb()
  // do stuff with result item...
curious
  • 791
  • 2
  • 12
  • 27
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – nicholaswmin Oct 26 '19 at 14:12

1 Answers1

1

What currently happens in your code is getFromDb function will run dynamoDb.get(...) and immediately return (undefined in your case, because there is no return statement inside getFromDb). By the time getFromDb returns, your dynamoDb request hasn't even resolved yet, it will resolve at some point in the future and call the callback you provided (error, result) => { ... }

To achieve what you described, you need to:

  1. make getFromDb return Promise which will only resolve after your request resolves
  2. await for that function when calling it, getting result into which your Promise resolves (or and error if it rejects)

.

// marking this function async is not required but good to have
// to not forget that this function returns a promise, not immediate result
const getFromDb = async () => {
  // wrapped body in a promise
  return new Promise((resolve, reject) => {
    const params = {
      TableName: table,
      Key: {
        id: id
      },
    }

    dynamoDb.get(params, (error, result) => {
      if (error) {
        // in case of error, we reject promise with that error
        reject(error)
        return
      }
      // otherwise, we resolve with result
      resolve(result.Item)
    })
  })
}

// usage with async/await
// I wrapped significant code in asynchronous function f and then called it
// just to emphasize that you can only use async/await inside async function
// if you are already in async function, you don't need to do this
const f = async () => {
  try {
    const item = await getFromDb();
    console.log(item)
  } catch(error) {
    // the error we rejected with
    console.error(error)
  }
}

f()


// alternative way without async/await, using Promise chaining
getFromDb()
  .then(item => console.log(item))
  .catch(error => console.error(error))
Max
  • 4,473
  • 1
  • 16
  • 18