0
votes

I have a working asynchronous call to dynamoDB:

  async getCostCenterTagFromTable() {
    // Create the DynamoDB service object
    var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
    var params = {
      TableName: 'csv-table',
      Key: {
        'BusinessUse': {S: 'eWFM'}
      },
      ProjectionExpression: 'CostCenter'
    };
    try {
      // Asynchronously retrieve value from DynamoDB
      const costCenter = await ddb.getItem(params).promise();
      return costCenter;
    }catch (error) {
      console.error(error);
    }
  }

I'm able to view the contents inside of the returned Promise just fine, but I just can not figure out how to remove the value from inside the then() block and return it to another function. My getCostCenterTagValue function needs to return a string. That string happily resides inside the promise's then() block. I need to take it out and return it, but it always comes back as undefined. I know this is an issue with the asynchronous nature of this call, and I've tried everything to get that value out of the then block to no avail. Any assistance would be greatly appreciated!

  getCostCenterTagValue() {
    var costCenter = this.getCostCenterTagFromTable();
    costCenter.then(console.log);
    //INFO  { Item: { AutoTag_CostCenter: { S: '1099:802:000000' } } }
    var costCenterString = costCenter.then(data => {
      console.log("Cost Center Tag:" + data.Item.AutoTag_CostCenter.S);
      //INFO Cost Center Tag:1099:802:000000
      return data.Item.AutoTag_CostCenter.S;
    }).catch(function(err) {
      console.log(err);
    });
    console.log(costCenter.then())
    return costCenterString(???); // or return costCenter.then(???)
  }
2
Anyone? Still struggling with this, Matt's answer does not meet requirements.user2774004

2 Answers

1
votes

The problem is that async getCostCenterTagFromTable() returns a promise. Because of that, you need to await the value where it's consumed, like so:

async getCostCenterTagValue() {
    var costCenter = await this.getCostCenterTagFromTable();

    var costCenterString = costCenter.Item.AutoTag_CostCenter.S;

    return costCenterString; 
  }

function logCostCenterTagValue() {
    getCostCenterTagValue().then(console.log);
}

This doesn't really have anything to do with AWS or Dynamo, it's purely an async issue: Check out this well-loved answer for more info: How do I return the response from an asynchronous call?

-1
votes

After much frustration I finally found a clean, easy solution to this problem: Deasync! This should really be a feature built in, and is exactly what I needed. This allows me to use a variable from an asynchronous call without being limited to the extremely narrow scope of a then() block inside a promise, and my function can return a string instead of a silly promise, immediately.

  getCostCenterTagValue() {
    let _data;
    let done = false;
    // Create the DynamoDB service object
    var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
    var params = {
      TableName: 'csv-table',
      Key: {
        'BusinessUse': {S: 'eWFM'}
      },
      ProjectionExpression: 'AutoTag_CostCenter'
    };
    try {
      // Retrieve the item
      ddb.getItem(params).promise().then((data) => {
        _data = data.Item.AutoTag_CostCenter.S;
        done = true;
        console.log("CostCenter: " + _data);
    });
    }catch (error) {
       console.error(error);
    }
    // Wait for asynchronous call to complete!
    require('deasync').loopWhile(function(){return !done;});
    return _data;
  }

Makers of this should give themselves a pat on the back! Thankyou creators of Deasync :)

https://www.npmjs.com/package/deasync