-1

I am trying to connect my front-end, via a lambda function, to DynamoDB. I cannot understand how to fix the lambda function for it to work. Currently it is just posting undefined to PK and SK.

Lambda Function

"use strict";
require("dotenv").config();
// const config = require("../../config/keys");
const AWS = require('aws-sdk')
AWS.config.update({ region: "eu-west-1" });
const documentClient = new AWS.DynamoDB.DocumentClient();

const addJobListing = async (data) => {
  const body = {
    TableName: "XXXXXX",
    Item: {
      "PK": `${data.acc}${data.jobId}${data.startDate}`,
      "SK": `${data.jobId}.${data.startDate}`,
      "Days Off": data.daysOff,
      "Start Date": data.startDate,
      "Job ID": data.jobId,
      "Contract Length": data.contractLength,
      "Expiration Date": data.expirationDate,
      Created: {
        M: {
          CREATED: {
            M: { date: data.createdDate, time: data.createdTime },
          },
        },
      },
      Insurance: data.insurance,
      Title: data.title,
      Holidays: data.holidays,
      Ages: data.ages,
      "Flight Reimbursement": data.flightReimbursement,
      Curriculum: data.curriculum,
      "Account ID": data.accountId,
      "Minimum Monthly Salary Before Tax": data.minimumMonthlySalaryBeforeTax,
      "Housing Allowance": data.housingAllowance,
      Responsibilities: data.responsibilities,
      "Job Closest Metro": data.jobClosestMetro,
      "Job Requirements": data.jobRequirements,
      "Job Type": data.jobType,
      "Z-VISA Reimbursement": data.zVisaReimbursement,
      Meals: data.meals,
      Subject: data.subject,
      "Salary Information": data.salaryInformation,
      "Maximum Monthly Salary Before Tax": data.maximumMonthlySalaryBeforeTax,
      "Vacancy Status": data.vacancyStatus,
      "Contract Completion Bonus": data.contractCompletionBonus,
      "Last Modified": {
        M: {
          LAST_MODIFIED: {
            M: {
              date: data.modifiedDate,
              time: data.modifiedTime,
            },
          },
        },
      },
    },
  };

  console.log("Job Listing ID", `${data.jobId}.${data.startDate}`);
  return await documentClient.put(body).promise();
};

exports.handler = async (event, context, callback) => {
  console.log("PRINT STRING", event);
  const response = await addJobListing(JSON.parse(event.body));
  console.log("resp", response);
  return {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Origin": "*", // Required for CORS support to work
      "Access-Control-Allow-Credentials": true, // Required for cookies, authorization headers with HTTPS
    },
    body: JSON.stringify(response),
  };
};

On CloudWatch, the errors are: resp undefined, Job Listing ID undefined.undefined.

 body: '{\r\n' +
    '    "Item": {\r\n' +
    '    "PK": "ACC#010117/01/2022",\r\n' +
    '    "SK": "01.17/01/2022",\r\n' +
    '    "Start Date": "17/01/2022",\r\n' +
    '    "Job ID": "01"\r\n' +
    '    }\r\n' +
    '  }',

The data I am sending to the endpoint API via API Gateway is this JSON:

{
    "Item": {
    "PK": "ACC#010117/01/2022",
    "SK": "01.17/01/2022",
    "Start Date": "17/01/2022",
    "Job ID": "01"
    }
  }

Postman Information Returned

Request Headers:
Content-Type: application/json
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: xxxxxxxxx
Host: xxxxxxxxxxx-execute.aws.eu-west-1.amazonaws.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 130

Request Body:
Response Headers
Date: Mon, 17 Jan 2022 18:39:41 GMT
Content-Length: 0
Connection: keep-alive
access-control-allow-origin: *
access-control-allow-credentials: true
Apigw-Requestid: xxxxxxxxxxxxxxx

Response Body:
0

1 Answers1

1

Looking at the JSON of your request body:

{\r\n' +
    '    "Item": {\r\n' +
    '    "PK": "ACC#010117/01/2022",\r\n' +
    '    "SK": "01.17/01/2022",\r\n' +
    '    "Start Date": "17/01/2022",\r\n' +
    '    "Job ID": "01"\r\n' +
    '    }\r\n' +
    '  }

There is no key acc, or jobId or startDate or really any of the keys you are trying to use. The key names have capital letters and spaces in them. And acc is definitely not a key at all.

So for example this:

   "PK": `${data.acc}${data.jobId}${data.startDate}`,

Needs to be this:

   "PK": data['PK'],

And this:

   "Job ID": data.jobId,

Needs to be this:

   "Job ID": data['Job ID'],
Mark B
  • 183,023
  • 24
  • 297
  • 295
  • Hi Mark, I had to add data["Item"]["Job ID"] for it to work. Would you have any idea how to make it work for Mapped or SS attributes as well as strings? –  Jan 18 '22 at 10:59
  • I don't understand what you mean by "mapped or SS attributes". – Mark B Jan 18 '22 at 14:14
  • Hi Mark, AWS defines attributes. You can find more information here: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_AttributeValue.html –  Jan 18 '22 at 14:29
  • Those are attribute types, and they are DynamoDB attributes that you need to build from the String that were submitted to your API Gateway and passed into your function. – Mark B Jan 18 '22 at 14:32
  • Last question: For adding a Created column in the table, I am trying to recreate this with JSON: { "CREATED" : { "M" : { "date" : { "S" : "12/01/2022" }, "time" : { "S" : "09:02:12:00" } } } } How would you advise writing the JSON to reproduce this in the DynamoDB Table? –  Jan 18 '22 at 15:04