Reputation: 5986
I have a complex amount of code for dynamodb calls to the database. Basically I have several database calls to linked at the end of each other, and then on top of that I need to loop through multiple items. Then at the end I need to be able to send a new JSON object to the front-end to display properly. The problem is that the Map finishes before the Database calls finish, so the "newItems" variable is undefined. Basically I need the map to wait for the database to finish before going to the next iteration.
The code snippet is not the complete call, but it's the relevant area. This is all wrapped in an app.get() as well.
const newItems = items.map(function(item, i) {
dynamoDb.scan({
TableName: GIVEAWAY_ENTRIES_TABLE,
FilterExpression: "giveawayId = :giveawayId",
ExpressionAttributeValues: {
":giveawayId": item.id
}
}, (error, ge_result) => {
dynamoDb.scan({
TableName: USERS_TABLE,
FilterExpression: "sessionId = :sii",
ExpressionAttributeValues: {
":sii": sessionId
}
}, (error, result) => {
dynamoDb.scan({
TableName: GIVEAWAY_ENTRIES_TABLE,
FilterExpression: "giveawayId = :giveawayId and userId = :userId",
ExpressionAttributeValues: {
":giveawayId": item.id,
":userId": result.Items[0].id
}
}, (error, gemc_result) => {
console.log("RESPONSEEEEEEE");
return {
id: item.id,
title: item.title,
thumbnail: item.thumbnail,
photo: item.photo,
description: item.description,
myCount: gemc_result.Count,
totalCount: ge_result.Count
}
});
});
})
console.log("END OF MAPPPPP");
});
console.log("#######", newItems);
res.json({'success': true, data: newItems});
Upvotes: 0
Views: 1617
Reputation: 1519
First thing I recommend you is to use the native function promisify to make AWS sdk functions returns a promise
. It's way more readable! Then you can take advantage of node.js promises to handle async code, you can use it like that:
const util = require('util');
const safePromisify = function (fun, methodsArray) {
const suffix = 'Async';
methodsArray.forEach(method => {
fun[method + suffix] = util.promisify(fun[method]);
});
}
safePromisify(dynamoDb, ['scan']);
const newItems = items.map(function async(item, i) {
// ^^^^^ this is required to use await
// Note the async and await keywords
let ge_result = await dynamoDb.scanAsync({
TableName: GIVEAWAY_ENTRIES_TABLE,
FilterExpression: "giveawayId = :giveawayId",
ExpressionAttributeValues: {
":giveawayId": item.id
}
});
let result = await dynamoDb.scanAsync({
TableName: USERS_TABLE,
FilterExpression: "sessionId = :sii",
ExpressionAttributeValues: {
":sii": sessionId
}
});
let gemc_result = await dynamoDb.scanAsync({
TableName: GIVEAWAY_ENTRIES_TABLE,
FilterExpression: "giveawayId = :giveawayId and userId = :userId",
ExpressionAttributeValues: {
":giveawayId": item.id,
":userId": result.Items[0].id
}
});
return {
id: item.id,
title: item.title,
thumbnail: item.thumbnail,
photo: item.photo,
description: item.description,
myCount: gemc_result.Count,
totalCount: ge_result.Count
}
});
Note: You have to append the word
Async
on the function call
Upvotes: 3