Tim Rooke
Tim Rooke

Reputation: 376

DynamoDB.putItem function not saving item with sls command

I am having trouble with my Lambda function with Serverless framework, which should be putting data to DynamoDB. I'm unsure of the issue as I am getting no error message in the console when I run: sls invoke local -f scrape -d 'the-last-bookstore-los-angeles.

saveRatingsToDB.js

const uuid = require('uuid');
const AWS = require('aws-sdk');

const dynamoDb = new AWS.DynamoDB.DocumentClient();

module.exports = (data, businessName) => {
  console.log('data saving...');
  console.log(data);
  const params = {
    TableName: process.env.DYNAMODB_TABLE,
    Item: {
      id: uuid.v1(),
      businessName: businessName,
      reviewCount: data.reviewCount,
      rating: data.rating,
      createdAt: JSON.stringify(new Date())
    }
  };

  // I am can log params okay, but nothing with dynamoDb.put is logged to the console

  dynamoDb.put(params, error => {
    console.log('putting data');
    if (error) {
      console.log(`Error saving data to DynamoDB: ${JSON.stringify(error)}`);
      return Promise.reject(
        `Error saving data to DynamoDB: ${JSON.stringify(error)}`
      );
    } else {
      console.log('data saved');
      return Promise.resolve(params.Item);
    }
  });
};

handler.js

'use strict';
const { getPage, parsePage, saveRatingsToDB } = require('./utils');

module.exports.scrape = async (event, context) => {
  console.log('Function triggered', event);
  const name = event;
  const page = await getPage(name);
  const data = await parsePage(page);
  const db = await saveRatingsToDB(data, name);

  return db;
};

serverless.yaml

provider:
  name: aws
  runtime: nodejs8.10
  stage: dev
  region: eu-west-2
  environment:
    DYNAMODB_TABLE: my-table-name
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: "arn_reference_"
package:
  include:
    - utils/**

As mentioned, I get no error message in the console. I can the log and see the params object from the saveRatingsToDB.js, but nothing within the actual dynamoDb.put function.

Any help would be appreciated.

Upvotes: 2

Views: 2051

Answers (1)

Thai Duong Tran
Thai Duong Tran

Reputation: 2522

You tried to run saveRatingsToDB as an asynchronous function by doing:

const db = await saveRatingsToDB(data, name);

Unfortunately, with the way this function is written currently, it's not an asynchronous function. The reason while you don't see the log inside dynamoDb.put is because the saveRatingsToDB function doesn't wait for the asynchronous callback to finish but return earlier.

To make saveRatingsToDB properly an asynchronous function and force it to wait for the callback, you can return a dynamoDb.put as a promise from that function:

module.exports = (data, businessName) => {
  ...

  // use dynamoDb.put().promise() to return a promise from dynamoDb transaction
  return dynamoDb.put(params, error => {
    ...
    // Do whatever with the error
  }).promise();
};

Upvotes: 3

Related Questions