AWS Lambda Node Js - Increment value if exist else add element - node.js

I want increment value if exist else add element.
+-----------------------+
| id | iteration | data |
+-----------------------+
| 10 | 1 | foo1 |
| 11 | 1 | foo2 |
| 12 | 2 | foo3 |
+-----------------------+
my code:
var AWS = require('aws-sdk');
var documentClient = new AWS.DynamoDB.DocumentClient({'region': 'eu-west-1'});
exports.handler = function(event, context, callback) {
var params = {
Item: {
id: uuid,
iteration: 1,
data: body.data
},
TableName: "my-table"
};
documentClient.put(params, function(err, data) {
if (err) {
console.log("Error", err);
const errResponse = {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({ Error: 500, device : "DynamoDB", detail : err })
};
callback(null, errResponse);
} else {
console.log("Success", params.Items);
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify("thanks")
};
callback(null, response);
}
});
}
My insert is OK.
I try with:
var params = {
TableName: "my-table",
Key:{
"id": uuid
},
UpdateExpression: "set iteration = iteration + :val",
ExpressionAttributeValues:{
":val": 1
},
ReturnValues:"UPDATED_NEW"
};
documentClient.update(params, function(err, data) {
if (err) {
console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
const errResponse = {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({ Error: 500, device : "DynamoDB", detail : err })
};
callback(null, errResponse);
} else {
console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify("thanks")
};
callback(null, response);
}
});
Update is OK (increment -> 2)
But I want increment value ONLY if exist else ONLY add element. Both methods are asynchronous, how should I do?

Your 2nd answer is close. In your UpdateExpression you need both and ADD and a SET on the same line. like the following:
UpdateExpression: "ADD iteration :iteration SET itemdata = :itemdata",
This is formally documented in the AWS DOCS for UpdateItem under DynamoDB
scrolling down it says
ADD - Adds the specified value to the item, if the attribute does not
already exist. If the attribute does exist, then the behavior of ADD
depends on the data type of the attribute:
If the existing attribute is a number, and if Value is also a number,
then Value is mathematically added to the existing attribute. If Value
is a negative number, then it is subtracted from the existing
attribute.
I was able to find a AWS forum post that had a successful upsert, as well as another SO answer with the ADD and SET syntax in the same line. Below is some code that will run if placed in a new lambda (change your region to match where your table is)
var AWS = require('aws-sdk');
var documentClient = new AWS.DynamoDB.DocumentClient({'region': 'eu-central-1'});
exports.handler = function(item, context, callback) {
var params = {
TableName: "my-table",
Key:{
"id": item.id
},
UpdateExpression: "ADD iteration :iteration SET itemdata = :itemdata",
ExpressionAttributeValues:{
':iteration': 1,
':itemdata' : item.data
},
ReturnValues:"NONE"
};
documentClient.update(params, function(err, data) {
if (err) {
console.log("Error", err);
const errResponse = {
statusCode: 500,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({ Error: 500, device : "DynamoDB", detail : err })
};
callback(null, errResponse);
} else {
console.log("Success", params.Items);
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify("upsert complete.")
};
callback(null, response);
}
});
};
note: data is a reserved keyword, and I got the following error:
Invalid UpdateExpression: Attribute name is a reserved keyword; reserved keyword: data
consider changing it to something else. I used itemdata.
Running it once will insert a new record. The following images are before and after images of the table after I run the lambda the second time.

Related

How to post a body correctly in Postman

I try to make a post request to an api but, api returns error. Although I thought about it for a long time, I could not find the cause of the error.
I think the error is due to not creating the body correctly because when I send empty array as items array the code works.
API DOCUMENTATION:
Here is my request:
module.exports.createOrder = (token, paymentId, items, callback) => {
const url = urlBase;
request(
{
url: url,
method: "POST",
json: true,
headers: {
"content-type": "application/json",
Authorization: `Bearer ${token}`,
},
body: {
secretKey: `${secretKey}`,
paymentId: paymentId,
items: items,
},
},
(error, response) => {
if (error) {
Sentry.captureException(error);
callback(errMessage, undefined);
} else {
const data = response.body;
callback(undefined, data);
}
}
);
};
Here is test values:
const testToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYyM2RmYjg4NDA4M2IwMDAyNDNjYzRhNyIsImlhdCI6MTY0ODIyOTI1NywiZXhwIjoxNjQ4MzE1NjU3fQ.9fgR3ei81vsHVMhSi8VwEyE2WMgFIMthm0PF9_zrqjw"
const paymentId = "pi_1Dq2f62eZvKYlo2Cy1moIb0G"
const variant = {
variations_values: {
color:'Black',
size:'42'
},
price:495,
product_id: "883360511078"
}
const productId = "82936941"
const quantity = 1
const item = {
variant:variant,
productId:productId,
quantity:quantity
}
let items = [item]
orderRequests.createOrder(testToken, paymentId, items, (err, data) => {
if(data){
console.log(data)
} else{
console.log(err)
}
})
I get internal server error as a response when I post these test values, but If I post an empty array as items, api does not return internal server error. What is the problem, any help?
Internal Server Error Response when I send an array with post body:
Expected request when I send an empty array with post body:

Getting { code: 200, message: 'Invalid api key or secret.' } when creating a Zoom meeting

I have an app that connects doctors with patients. When I use the API to create a meeting for the doctor, I get the following error:
{ code: 200, message: 'Invalid api key or secret.' }
var defer = Q.defer();
var op = {
method: "POST",
uri: "https://api.zoom.us/v2/users/" + options.email + "/meetings",
body: {
topic: "test.com 1-1 session",
type: 2,
start_time: new Date(options.startDate),
duration: 40,
settings: {
host_video: "true",
participant_video: "true"
}
},
headers: {
'content-type': 'application/json',
authorization: `Bearer ${options.refreshToken}`
},
json: true //Parse the JSON string in the response
};
request.post(op, (error, response, body) => {
if (error) {
defer.reject(error);
}
defer.resolve(body);
});
return defer.promise;
Can someone please help?

How to remove a nested attribute from dynamodb table?

How to remove a nest attribute from dynamodb table on the basis of id? I m using nodejs(Typescript) with local dynamodb.
// check if post exists
const post = await dynamo.get({
TableName: "PostTable",
Key: { id: event.body.postId }
}).promise();
if (!post.Item) {
return formatJSONResponse({
message: `no post with this id`,
statuscode: 404
});
}
const params = {
TableName: "PostTable",
Key: { id: event.body.postId },
UpdateExpression:
"REMOVE comments.#id",
ExpressionAttributeValues: {
"#id": event.body.id
},
ReturnValues : "UPDATED_NEW"
}
let res= await dynamo.update(params).promise();
return formatJSONResponse({
message: `Comment has been removed
event,
result: res
});
dynamobdb table picture

Push notification returns ECONNRESET in Google Cloud Functions

I am having a function in Firebase Cloud Functions that is retrieves the user's device group id in order to send a push notification, and after sends a push notification. This works well if the function gets called only once, but if I have an array of users I want to send a push notification too, the sendPushNotification function returns error : FAILED err= { RequestError: Error: read ECONNRESET
at new RequestError (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/errors.js:14:15) for every try to send push
From what i understand ECONNRESET means that the connection gets closed at one end before finishing the operation, can some help/explain me why this is:
here is my code:
function sendFollowNotification(snapshot) {
const notificationMsg = getFollowNotificationMsg() //returns a string
snapshot.forEach(function(singleUser, index) {
const userId = singleUser.key;
const userObject = singleUser.val();
console.log("will get device group")
if (index + 1 == snapshot.numChildren()) {
return getDeviceGroupNotificationKey(userId, "Discover new artists", notificationMsg, "", true);
} else {
getDeviceGroupNotificationKey(userId, "Discover new artists", notificationMsg, "", false);
}
}
function getDeviceGroupNotificationKey(groupId, notificationTitle, notificationBody, notificationSubject, shouldReturn) {
const pathToDeviceGroup = admin.database().ref('deviceGroups').child(groupId);
pathToDeviceGroup.once("value").then( function(snapshot) {
const deviceGroupObj = snapshot.val();
const notification_key = deviceGroupObj.notification_key;
console.log("got notification key")
console.log(notification_key)
if (notification_key !== undefined) {
return sendPushToDeviceGroupOld(notification_key, notificationTitle, notificationBody, "notificationKeyOld2", notificationSubject, shouldReturn);
} else {
return
}
}).catch(reason => {
console.log("user device group not there")
return
})
}
function sendPushToDeviceGroupOld(notification_key, title, body, subject, message, shouldReturn) {
console.log('sending push to ' + notification_key)
const serverKey = '-';
const senderId = '-';
const options = {
method: 'POST',
uri: 'https://fcm.googleapis.com/fcm/send',
headers: {
'Authorization': 'key=' + serverKey,
'project_id': senderId
},
body: {
to: notification_key,
data: {
subject: message
},
notification: {
title: title,
body: body,
badge: 1,
sound: "default",
},
priority : 'high',
content_available: true
},
json: true
};
return rqstProm(options)
.then((parsedBody) => {
console.log('SUCCESS response=', parsedBody);
return
})
.catch((err) => {
console.log('FAILED', err);
return
});
}

Passing array or nested objects in body of request npm

I have to send some parameters of String type along with one array in my body.
But it throws me an error message:
First argument must be String or buffer
Here is my code:
var tokenList = JSON.parse(req.body.tokenList);
var mobParams = {
"tokens": tokenList,
"profile": "<myprofile>",
"notification": {
"title": req.body.title,
"message": req.body.text
}
};
request({
method: "POST",
url: 'https://api.ionic.io/push/notifications',
headers: {
"content-type": "application/json",
"authorization": "Bearer ********"
},
body: (mobParams)
}, function(error, response, body){
console.log('Ionic push error', error);
console.log('IOnic push res', response);
console.log('IOnic push body', body);
if(!error){
return res.send({
code: 1,
message: "success"
});
}else{
return res.send({
code: 0,
message: error
});
}
How can I pass my array inside this object to request npm?
Also, I would like to add that this implementation works pretty fine through front-end but I have separate codebase which requires me to hit multiple FCM requests i.e. in a loop. So I would be happy to have a solution as neither ionic push nor FCM push works
For the FCM push I am trying the code below :
let desktopParams = {
"notification": {
"title": 'Merchant Portal Notifications',
"body": req.body.text
// "click_action" : action
},
"to": '/topics/' + topic
};
request({
method: "POST",
json: true,
url: 'https://fcm.googleapis.com/fcm/send',
headers: {
"content-type": "application/json",
"authorization": "key=****"
},
body: desktopParams
}, function(error, response, body){
console.log('error', error);
console.log('response', response);
console.log('body', body);
//return body;
});
you should try stringifying your tokenList & req.body.text before you join it with with the string (try to log it and post the outcome so that people will have a better idea about the objects...):
var cho = [{name:'john',lname:'cena'},{name:'mary',lname:'jane'}];
var che = {list:[{name:'john',lname:'cena'},{name:'mary',lname:'jane'}],group:'people'}
var mobParams = {
"tokens":JSON.parse(JSON.stringify(cho)),
"profile": "<myprofile>",
"notification": {
"title": "Some title",
"message":JSON.parse(JSON.stringify(che))
}
};
console.log(JSON.stringify(mobParams));//----->{"tokens":[{"name":"john","lname":"cena"},{"name":"mary","lname":"jane"}],"profile":"<myprofile>","notification":{"title":"Some title","message":{"list":[{"name":"john","lname":"cena"},{"name":"mary","lname":"jane"}],"group":"people"}}}
var arr = [{name:'john',lname:'cena'},{name:'mary',lname:'jane'}]
var js = JSON.stringify(arr);
var blabla = {'item':'something',js}
console.log(blabla); //-----> Object {item: "something", js: "[{"name":"john","lname":"cena"},{"name":"mary","lname":"jane"}]"}
var js = JSON.parse(JSON.stringify(arr));
var blabla = {'item':'something',js}
console.log(blabla); //-----> Object {item: "something", js: Array(2)}
var js = JSON.parse(arr);
var blabla = {'item':'something',js}
console.log(blabla); //-----> "SyntaxError: Unexpected identifier"

Resources