0

AWS Lambda (JavaScript/TypeScript) here. I have the following Lambda handler:

import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import { User, allUsers } from './users';
import { Commentary } from './domain';
import { dynamoDbClient } from './store';
import { PutCommand } from "@aws-sdk/client-dynamodb";

export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
    try {

        let status: number = 200;
        let commentary: Commentary = JSON.parse(event.body);
        console.log("deserialized this into commentary");
        console.log("and the deserialized commentary has content of: " + commentary.getContent());
        provideCommentary(event.body);
        responseBody = "\"message\": \"received commentary -- check dynamoDb!\"";

        return {
            statusCode: status,
            body: responseBody
        };

    } catch (err) {
        console.log(err);
        return {
            statusCode: 500,
            body: JSON.stringify({
                message: err.stack,
            }),
        };
    }
};

const provideCommentary = async (commentary: Commentary) => {
  // Set the parameters.
  const params = {
    TableName: "commentary-dev",
    Item: {
      id: commentary.getId(),
      content: commentary.getContent(),
      createdAt : commentary.getCreatedAt(),
      providerId: commentary.getProviderId(),
      receiverId: commentary.getReceiverId()
    },
  };
  try {
    const data = await ddbDocClient.send(new PutCommand(params));
    console.log("Success - item added or updated", data);
  } catch (err) {
    console.log("Error", err.stack);
    throw err;
  }
};

Where the Commentary class in domain.ts is:

class Commentary {
  private id: number;
  private content: string;
  private createdAt: Date;
  private providerId: number;
  private receiverId: number;

  constructor(id: number, content: string, createdAt: Date, providerId: number, receiverId: number) {
    this.id = id;
    this.content = content;
    this.createdAt = createdAt;
    this.providerId = providerId;
    this.receiverId = receiverId;
  }

  public getId(): number {
    return this.id;
  }

  public getContent(): string {
    return this.content;
  }

  public getProviderId(): number {
    return this.providerId;
  }

  public getReceiverId(): number {
    return this.receiverId;
  }

}

export { Commentary };

When I invoke my Lambda, via command-line curl:

curl --request POST 'https://<mylambda>/commentary' \
--header 'Content-Type: application/json' -d '{"id":123,"content":"test commentary","createdAt":"2022-12-02T08:45:26.261-05:00","providerId":456,"receiverId":789}'

...I see the following error in my terminal:

{"message":"TypeError: r.getContent is not a function\n

Any idea why event.body is having trobule being deserialized into a Commentary?

hotmeatballsoup
  • 385
  • 6
  • 58
  • 136
  • Are you making this POST request via API Gateway, or directly to a Lambda function URL? – jarmod Dec 02 '22 at 18:42
  • 1
    BTW you might consider using TypeScript [get/set accessors](https://stackoverflow.com/questions/51646513/getter-setter-in-typescript) rather than the Java-esque getter/setter methods. – jarmod Dec 02 '22 at 18:55

1 Answers1

0

You haven't properly constructed a Commentary instance. Instead, you have just set the commentary variable's value to the parsed body, a plain-old object.

const { id, content, createdAt, providerId, receiverId } = JSON.parse(event.body);

const commentary = new Commentary(id, content, createdAt, providerId, receiverId);
fedonev
  • 20,327
  • 2
  • 25
  • 34