0
votes

I am a beginner in AWS and am stuck now. I was able to create a web page to collect Contact US details and write it to DynamoDB table named "WebUser-ContactUS". I created another (reference) table with assignments, where I specify that the table "WebUser-ContactUS" is to be handled by the employee GiselleS for now. I am hoping to get the name of the table thru this lambda function and display its content dynamically according to the employee's id.

Here is my current code to get the record from the reference table and it returns NULL (Succeeds though):

// Load the AWS SDK for JS
var AWS = require("aws-sdk");

// Set a region to interact with (make sure it's the same as the region of your table)
AWS.config.update({region: 'us-west-2'});

// Create the Service interface for DynamoDB
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});

// Create the Document Client interface for DynamoDB
var ddbDocClient = new AWS.DynamoDB.DocumentClient();

// Get a single item with the getItem operation
function GetTasks(tblname, itemname, employee) {
        var params = {
        TableName: "map_Assignments",
        KeyConditionExpression: "#TaskID = :TaskIDValue",
        ExpressionAttributeNames: {
            "#TaskID":"TaskID",
        },
        ExpressionAttributeValues: {
            ":TaskIDValue": itemname,
        },
        Limit: 1
    };
        ddbDocClient.query(params, function(err, data) {
          if (err) { console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2)); return 'error'}
          else { console.log("Query succeeded:", JSON.stringify(data, null, 2)); return data}
        });
}

exports.handler = function (event, context, callback) {
    console.log('Received event:', event);
    // Setting up variables:
    const AssignmentID = event.AssignmentID;
    const Action = event.Action;
    // Calculating variables:
    const Tasks = GetTasks("map_Assignments", event.TaskID, event.EmployeeNetworkID);
    
    const response = {
        statusCode: 200,
        body: Tasks
    };
    callback(null, JSON.stringify(Tasks));
};

Here is the log: Response: null

Request ID: "cb1a88f6-6496-49a5-8ee5-aab3400d49e5"

Function logs: START RequestId: cb1a88f6-6496-49a5-8ee5-aab3400d49e5 Version: $LATEST 2020-07-08T19:50:30.694Z cb1a88f6-6496-49a5-8ee5-aab3400d49e5 INFO Received event: { EmployeeNetworkID: 'GiselleS', TaskID: 1, Action: 'Get' } 2020-07-08T19:50:31.394Z cb1a88f6-6496-49a5-8ee5-aab3400d49e5 INFO Query succeeded: { "Items": [ { "TaskName": "Customer Service", "TaskID": 1, "TaskDescription": "To handle web user messages submitted thru Contact Us form", "EmployeeNetworkID": "GiselleS", "CreateDt": "2020-07-04", "TableWithTaskDetails": "WebUser-ContactUS" } ], "Count": 1, "ScannedCount": 1 } END RequestId...


When I attempt to get the value of the table name with the last line switched to below, the function fails:

callback(null, JSON.stringify(Tasks[0].TableWithTaskDetails));

Here is the error message:

Response: { "errorType": "TypeError", "errorMessage": "Cannot read property '0' of undefined", "trace": [ "TypeError: Cannot read property '0' of undefined", " at Runtime.exports.handler (/var/task/index.js:44:40)", " at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)" ] }

Request ID: "f7934e30-21ff-430b-a583-c991af3ef9e2"

Function logs: START RequestId: f7934e30-21ff-430b-a583-c991af3ef9e2 Version: $LATEST 2020-07-08T19:42:19.688Z f7934e30-21ff-430b-a583-c991af3ef9e2 INFO Received event: { EmployeeNetworkID: 'GiselleS', TaskID: 1, Action: 'Get' } 2020-07-08T19:42:20.195Z f7934e30-21ff-430b-a583-c991af3ef9e2 ERROR Invoke Error {"errorType":"TypeError","errorMessage":"Cannot read property '0' of undefined","stack":["TypeError: Cannot read property '0' of undefined"," at Runtime.exports.handler (/var/task/index.js:44:40)"," at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"]} END RequestId...

Please help me move forward and get the value of the field TableWithTaskDetails "WebUser-ContactUS" as the result of this function.

1

1 Answers

0
votes

The GetTasks function doesn't return anything. The data object is only returned in the callback function of the ddbDocClient.query function.

Solving it with callbacks: Provide a callback to the GetTasksfunction:

function GetTasks(tblname, itemname, employee, cb) {
  var params = {
    TableName: 'map_Assignments',
    KeyConditionExpression: '#TaskID = :TaskIDValue',
    ExpressionAttributeNames: {
      '#TaskID': 'TaskID',
    },
    ExpressionAttributeValues: {
      ':TaskIDValue': itemname,
    },
    Limit: 1,
  };
  ddbDocClient.query(params, function (err, data) {
    if (err) {
      console.error(
        'Unable to read item. Error JSON:',
        JSON.stringify(err, null, 2)
      );
      cb(err, null);
    } else {
      console.log('Query succeeded:', JSON.stringify(data, null, 2));
      cb(null, data);
    }
  });
}

and in the lambda function:

exports.handler = function (event, context, callback) {
  console.log('Received event:', event);
  // Setting up variables:
  const AssignmentID = event.AssignmentID;
  const Action = event.Action;
  const response = {
    statusCode: 200,
    body: Tasks,
  };

  // Calculating variables:
  GetTasks('map_Assignments', event.TaskID, event.EmployeeNetworkID, function (
    err,
    data
  ) {
    if (data)
      callback(null, JSON.stringify(data.Items[0].TableWithTaskDetails));
    else callback(err, null);
  });
};