1

I have the following function definition. Essentially, what it does is query a DynamoDB table and return the deviceID of the corresponding partition key.

GetDeviceIdFromHash: function (id) {
    const params = {
        TableName: process.env.USER_TABLE,
        Key: {
            id: id
        }
    };
    dynamoDb.get(params, function(error, result) {
        // handle potential errors
        if (error) {
            console.log(error);
            return "";
        }
        return result;
    });
}

The problem is that this function ALWAYS returns undefined, irrespectively of whether or not the id attribute is present in the database.

I am not entirely sure as to why this is happening.

Based on my hunch, I'm thinking that this might be related to dynamoDb.get() being an async statement, but my experience with node.js is limited so I don't know how to proceed.

Caller to the function:

'use strict';

const AWS = require('aws-sdk'); // eslint-disable-line import/no-extraneous-dependencies
const dynamoDb = new AWS.DynamoDB.DocumentClient();
const push = require('./helper.js')

module.exports.update = async (event, context, callback) => {
    const data = JSON.parse(event.body);
    // validation
    if (typeof data.userid !== 'string' || typeof data.restaurantid !== 'string' || typeof data.orderTime !== 'string' || typeof data.status !== 'string'
        || typeof data.confirmedtime !== 'string' || typeof data.expecteddeliverytime !== 'string' || typeof data.readytime !== 'string' || typeof data.contents !== 'string') {
        console.error('Validation Failed');
        callback(null, {
            statusCode: 400,
            headers: { 'Content-Type': 'text/plain' },
            body: 'Couldn\'t update the order',
        });
        return;
    }

    const params = {
        TableName: process.env.ORDER_TABLE,
        Key: {
            id: event.pathParameters.id,
        },
        ExpressionAttributeNames: {
            '#userid': 'userid',
            '#restaurantid': 'restaurantid',
            '#orderTime': 'orderTime',
            '#status': 'status',
            '#confirmedtime': 'confirmedtime',
            '#expecteddeliverytime': 'expecteddeliverytime',
            '#readytime': 'readytime',
            '#contents': 'contents',
        },
        ExpressionAttributeValues: {
            ':userid': data.userid,
            ':restaurantid': data.restaurantid,
            ':orderTime': data.orderTime,
            ':status': data.status,
            ':confirmedtime': data.confirmedtime,
            ':expecteddeliverytime': data.expecteddeliverytime,
            ':readytime': data.readytime,
            ':contents': data.contents
        },
        UpdateExpression: 'SET #userid = :userid, #restaurantid = :restaurantid, #orderTime = :orderTime, #status = :status, #confirmedtime = :confirmedtime, #expecteddeliverytime = :expecteddeliverytime, #readytime = :readytime, #contents = :contents',
        ReturnValues: 'ALL_NEW',
    };

    // update the address in the database
    dynamoDb.update(params, (error, result) => {
        // handle potential errors
        if (error) {
            console.error(error);
            callback(null, {
                statusCode: error.statusCode || 501,
                headers: { 'Content-Type': 'text/plain' },
                body: 'Couldn\'t update the order.'
            });
            return;
        }
        // send push notification of new order status
          var device_id = await push.GetDeviceIdFromHash(data.userid);
          var push_data = push.generatePushNotification("Order status update!", data.status);
          var res = push.sendPush(device_id, push_data);
          console.log(device_id);
          console.log(push_data);

        // create a response
        const response = {
            statusCode: 200,
            body: JSON.stringify(result.Attributes),
            headers: {
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Credentials': true
            }
        };
        callback(null, response);
    });
};
1
  • You are trying to await your GetDeviceIdFromHash function, which is not returning a Promise. This is a good example of why to prefer TS and why to have linters. A second problem is that you are using the "callback" wrong, it is a function, if you return from it, it'll return from the callback, not your encapsulating scope. The upvoted answer is correct, unless you want to pass another callback function into GetDeviceIdFromHash. Commented Sep 28, 2021 at 2:23

1 Answer 1

1

Yeah, that might occur due to asynchronous execution. So can you just try this and tell me:

GetDeviceIdFromHash: async function (id) {
    const params = {
        TableName: process.env.USER_TABLE,
        Key: {
            id: id
        }
    };
    let result = await dynamoDb.get(params).promise();
    return result;
}

Caller to the function:

'use strict';

const AWS = require('aws-sdk'); // eslint-disable-line import/no-extraneous-dependencies
const dynamoDb = new AWS.DynamoDB.DocumentClient();
const push = require('./helper.js')

module.exports.update = async (event, context, callback) => {
    const data = JSON.parse(event.body);
    // validation
    if (typeof data.userid !== 'string' || typeof data.restaurantid !== 'string' || typeof data.orderTime !== 'string' || typeof data.status !== 'string'
        || typeof data.confirmedtime !== 'string' || typeof data.expecteddeliverytime !== 'string' || typeof data.readytime !== 'string' || typeof data.contents !== 'string') {
        console.error('Validation Failed');
        callback(null, {
            statusCode: 400,
            headers: { 'Content-Type': 'text/plain' },
            body: 'Couldn\'t update the order',
        });
        return;
    }

    const params = {
        TableName: process.env.ORDER_TABLE,
        Key: {
            id: event.pathParameters.id,
        },
        ExpressionAttributeNames: {
            '#userid': 'userid',
            '#restaurantid': 'restaurantid',
            '#orderTime': 'orderTime',
            '#status': 'status',
            '#confirmedtime': 'confirmedtime',
            '#expecteddeliverytime': 'expecteddeliverytime',
            '#readytime': 'readytime',
            '#contents': 'contents',
        },
        ExpressionAttributeValues: {
            ':userid': data.userid,
            ':restaurantid': data.restaurantid,
            ':orderTime': data.orderTime,
            ':status': data.status,
            ':confirmedtime': data.confirmedtime,
            ':expecteddeliverytime': data.expecteddeliverytime,
            ':readytime': data.readytime,
            ':contents': data.contents
        },
        UpdateExpression: 'SET #userid = :userid, #restaurantid = :restaurantid, #orderTime = :orderTime, #status = :status, #confirmedtime = :confirmedtime, #expecteddeliverytime = :expecteddeliverytime, #readytime = :readytime, #contents = :contents',
        ReturnValues: 'ALL_NEW',
    };

    // update the address in the database
    dynamoDb.update(params, (error, result) => {
        // handle potential errors
        if (error) {
            console.error(error);
            callback(null, {
                statusCode: error.statusCode || 501,
                headers: { 'Content-Type': 'text/plain' },
                body: 'Couldn\'t update the order.'
            });
            return;
        }
        // send push notification of new order status
          var device_id = await push.GetDeviceIdFromHash(data.userid);
          var push_data = push.generatePushNotification("Order status update!", data.status);
          var res = push.sendPush(device_id, push_data);
          console.log(device_id);
          console.log(push_data);

        // create a response
        const response = {
            statusCode: 200,
            body: JSON.stringify(result.Attributes),
            headers: {
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Credentials': true
            }
        };
        callback(null, response);
    });
};
Sign up to request clarification or add additional context in comments.

3 Comments

Doesn't seem to work. Printing out result, I get: Promise { <pending>}
Can you just put the code after this function? I'll try to fix it.
Sorry, accidentally edited that into your post. Yikes!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.