DELETE method that integrates with a Lambda Function (AWS) - javascript

I will start this by saying that I know this is probably the worst JavaScript implementation you will see but I am required to use it for academic purposes.
I am required to make a static website and deploy an API Gateway for my application with GET, POST, and DELETE methods that integrate with a Lambda Function.
My GET and POST functions are functioning well but the problem is with the DELETE.
<script>
var url = 'The API endpoint';
var submitBtn = document.getElementById('submitBtn');
submitBtn.addEventListener('click', getDetails);
function getDetails(){
var mail = document.getElementById('mail').value;
var firstName = document.getElementById('firstName').value;
if(mail == '' || firstName == ''){
alert("Please submit valid data!");
return;
}
var params = '{"Item": {"email": "' + mail + '", "firstname": "' + firstName + '"}}';
httpDeleteAsync(url, params, processResponse);
}
function httpDeleteAsync(url, params, callback){
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
callback(xmlHttp.responseText);
}
}
console.log(params);
console.log(JSON.parse(params));
xmlHttp.open("DELETE", url);
xmlHttp.setRequestHeader('Content-type', 'application/json');
xmlHttp.send(params);
}
function processResponse(response){
document.getElementById('response').innerHTML = response;
}
</script>
The console doesn't display any errors, but I get a null response on my page when I try to delete.
Thanks in advance for any help.
UPDATE #1
I am starting to think that the problem is with the Lambda function not sure if I am right though.
var AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();
exports.handler = (event, context, callback) => {
// TODO implement
//console.log(event['body-json']);
var tableName = 'Customers';
var params = {
TableName: tableName,
Item : event['body-json'].Item
}
// docClient.put(params).promise().then(res => res).catch(err => err);
docClient.delete(params, function(err, data) {
if (err) {
console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
} else {
console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
}
});
};

I was treating the DELETE as the opposite of POST hence their processes being similar in code but I was mistaken. The DELETE had more in common with GET. So by thinking with that mindset I was able to solve the problem. Down bellow are the adjusted codes.
JAVASCRIPT:
<script>
var url = 'YOUR API'
var submitBtn = document.getElementById('submitBtn');
submitBtn.addEventListener('click', getDetails);
function getDetails(){
var mail = document.getElementById('mail').value;
if(mail == ''){
alert("Please submit a valid email!");
return;
}
var params = 'email=' + mail;
httpDelAsync(url, params, processResponse);
}
function httpDelAsync(url, params, callback){
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState == 4 && xmlHttp.status == 200){
callback(JSON.parse(xmlHttp.responseText));
}
}
console.log(params);
xmlHttp.open("DELETE", url + "/?" + params);
xmlHttp.send(null);
}
function isEmpty(obj) {
for(var key in obj) {
if(obj.hasOwnProperty(key))
return false;
}
return true;
}
function processResponse(response){
//console.log(response);
if(!isEmpty(response)){
document.getElementById('firstNameLabel').innerHTML = response.Item.firstname;
document.getElementById('mailLabel').innerHTML = response.Item.email;
document.getElementById('error').innerHTML = "";
}
else{
document.getElementById('firstNameLabel').innerHTML = '';
document.getElementById('mailLabel').innerHTML = '';
document.getElementById('error').innerHTML = "DELETED";
}
}
</script>
Lambda Function:
const AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();
var tableName = "Customers" // Put your Table Name Here
exports.handler = async (event) => {
console.log(event.email)
var params = {
TableName: tableName,
Key: {
email: event.email
}
};
return docClient.delete(params).promise().then(res => res).catch(err => err);
};
There is a slight problem with the response of the DELETE but it works fine so I left it as it is.

Related

How to modify anchor tags in botframework Web chat

We've just started using the bot-framework. For client side we are using the cdn and not react. We have certain links that bot responds with. And we would like to append a url parameter to each link and open the link in the same window. So far this is what my code looks like. Is there a better way to achieve this using the botframework. I know there is cardActionMiddleware which has openUrl cardAction, but we don't have any cards and I am not sure on how to implement that.
var webchatMount = document.getElementById('webchatMount');
function loadChatbot() {
var xhr = new XMLHttpRequest();
xhr.open('GET', "https://webchat.botframework.com/api/tokens", true);
xhr.setRequestHeader('Authorization', 'BotConnector ' + '<secret>');
xhr.send();
xhr.onreadystatechange = function (e) {
if (xhr.readyState == 4 && xhr.status == 200) {
var response = JSON.parse(xhr.responseText);
var store = window.WebChat.createStore({}, function ({ dispatch }) {
return function (next) {
return function (action) {
if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
var event = new Event('webchatincomingactivity');
event.data = action.payload.activity;
window.dispatchEvent(event);
}
return next(action);
}
}
});
window.WebChat.renderWebChat(
{
directLine: window.WebChat.createDirectLine({ token: response }),
store: store,
},
webchatMount
);
document.querySelector('.webchat__send-box-text-box__input').focus();
window.addEventListener('webchatincomingactivity', ({ data }) => {
setTimeout(function () {
var links = document.querySelectorAll('#webchatMount a');
if (links.length >= 1) {
for (var i = 0; i <= links.length; i++) {
if (links[i] == undefined)
break;
var compare = new RegExp('maindomain');
var href = links[i].getAttribute('href');
var st = getParameterByName('st', href);
if (links[i].hasAttribute('target')) {
links[i].removeAttribute('target');
}
if (compare.test(href)) {
// internal link
// check if it has st=INTRA
if (st) {
console.log(' it has a value');
} else {
links[i].setAttribute('href', insertParam('st', 'INTRA', href));
}
} else {
// external link, do nothing
}
}
}
}, 1000);
});
}
}
}
and here are getParameterByName and insertParam functions.
function getParameterByName(name, url) {
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
function insertParam(key, value, url) {
key = encodeURIComponent(key);
value = encodeURIComponent(value);
// kvp looks like ['key1=value1', 'key2=value2', ...]
var kvp = url.split('&');
var i=0;
for(; i<kvp.length; i++){
if (kvp[i].startsWith(key + '=')) {
var pair = kvp[i].split('=');
pair[1] = value;
kvp[i] = pair.join('=');
break;
}
}
if(i >= kvp.length){
kvp[kvp.length] = [key,value].join('=');
}
return kvp.join('&');
}
I am new to botframework webchat so I don't know it very well. I know that the secret should not be used like that, but for know we are testing and would like to get it to work. Any help would be appericiated
Thanks.

How to store multiple JavaScript objects from a file to a variable

So this how the app should work: with a Node.js script I call the coincap.io api, and I store the response of the various request in different files. Here is the script:
var request = require("request");
var fs = require("fs");
var cors = require("cors");
var parseString = require("xml2js").parseString;
var coinstore = [];
var endpoint = ["coins", "map", "front", "global"];
for (i = 0; i < endpoint.length; i++) {
request("http://coincap.io/" + endpoint[i], function(err, response, body) {
console.log("error", Error);
console.log("statusCode: ", response && response.statusCode);
//console.log("body: ", JSON.stringify(body));
var xml = body;
parseString(xml, function(err, result) {
console.log(xml);
coinstore.push(xml);
});
fs.writeFile("D:/bibblebit/response" + response.request.path.replace(/\//g, "") + ".json", coinstore,
function(err) {
if (err) {
console.log(err);
} else {
console.log("salvato!");
}
});
});
};
I then let the user make custom calls and retrieve data from those files.
Here is a working call:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
console.log("pronto!");
var alldata = [];
alldata.push(xhr.response);
var obj = JSON.parse(alldata);
console.log(obj);
document.getElementById("api-container").innerHTML += obj.altCap;
} else {
console.log("try again");
}
}
xhr.open("GET", "http://127.0.0.1:8081/responseglobal.json", true);
xhr.send(null);
This works because the file responseglobal.json has a single object.
Changing the last snippet into this one:
document.getElementById("api-container").innerHTML += obj.mktcap;
}
else {
console.log("try again");
}
}
xhr.open("GET", "http://127.0.0.1:8081/responsefront.json", true);
xhr.send(null);
returns a self explanatory error:
[Visualizza/nascondi dettagli messaggio.] SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data at line 1 column 264 of the JSON data
Every comma separating objects results in an unexpected character, which means I am not able to create one object for every object in the file or at least read a file with more than one object. What am I missing?
I may have missed the right approach. I can't find on the net a fitting explanation, since the questions I was able to find refer to manually created objects or so specific scenarios to become useless in my case to a different extent.
This is the server side script:
var request = require("request");
var fs = require("fs");
var cors = require ("cors");
var parseString = require("xml2js").parseString;
var endpoint = ["coins", "map","front", "global"];
var i = 0;
for (i=0 ; i<endpoint.length ; i++){
request("http://coincap.io/"+endpoint[i], function (err, response, body){
var coinstore = [];
console.log("error", Error);
console.log("statusCode: ", response && response.statusCode);
var xml =JSON.stringify(body);
parseString(xml, function (err, result){
console.log(xml);
coinstore.push(xml);
});
fs.writeFileSync("/response"+ response.request.path.replace(/\//g, "")+ ".json", coinstore, function(err){
if (err){
console.log(err);
}
else {
console.log("salvato!");
}
});
});
};
And this one is the client-side one:
var queries = [ "global", "coins", "map","front"];
for(i=0; i<queries.length; i++) {
pronto(i);
}
function pronto(i) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == XMLHttpRequest.DONE) {
console.log("pronto!");
var obj = JSON.parse(xhr.response);
//console.log(obj);
document.getElementById("api"+i+"-container").innerHTML+=obj;
console.log("stampato: "+ i);
} else {
console.log("bucato");
}
}
xhr.open("GET", "response"+ queries[i] +".json", true);
xhr.send(null);
}
They might not be the best solutions, but they work out.

jQuery.post() dynamically generated data to server returns empty response

I'm generating a series of variables in a loop (using JS), and I'm assigning them an .id and a .name based on the current index. At each loop I'm sending a request to the server using jQuery.post()method, but the returning response is just an empty variable.
Here's the code:
JavaScript
for ( var index = 0; index < 5; index++ ) {
var myVar = document.createElement('p');
myVar.id = 'myVarID' + index;
myVar.name = 'myVarName' + index;
//Send request to server
$(document).ready(function(){
var data = {};
var i = 'ind';
var id = myVar.id;
var name = myVar.name;
data[id] = name;
data[i] = index;
$.post("script.php", data, function(data){
console.log("Server response:", data);
});
});
}
PHP
<?php
$index = $_POST['ind'];
$myVar = $_POST['myVarID'.$index];
echo $myVar;
?>
Response: Server response: ''
If I instead set a static index in JS code, getting rid of the loop, so for example:
var index = 0;
I get the expected result: Server response: myVarName0
Why is this happening? And how can I solve it?
Assuming the php file is in order. I use this:
function doThing(url) {
getRequest(
url,
doMe,
null
);
}
function doMe(responseText) {
var container = document.getElementById('hahaha');
container.innerHTML = responseText;
}
function getRequest(url, success, error) {
var req = false;
try{
// most browsers
req = new XMLHttpRequest();
} catch (e){
// IE
try{
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
// try an older version
try{
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function () {};
if (typeof error!= 'function') error = function () {};
req.onreadystatechange = function(){
if(req .readyState == 4){
return req.status === 200 ?
success(req.responseText) : error(req.status)
;
}
}
var thing = "script.php?" + url;
req.open("GET", thing, true);
req.send(null);
return req;
}
then use it like this:
doThing("myVarID="+myVar.id+"&i="+index);
also, you will have to change your PHP to something like this:
<?php
$index = $_GET['ind'];
$myVar = $_GET['myVarID'.$index];
echo $myVar;
?>
Obviously this code needs to be edited to suit your own needs
the function doMe is what to do when the webpage responds, in that example I changed the element with the id hahaha to the response text.
This won't win you any prizes but it'll get the job done.
Solution
It is working fine removing:
$(document).ready()
Working code
for ( var index = 0; index < 5; index++ ) {
var myVar = document.createElement('p');
myVar.id = 'myVarID' + index;
myVar.name = 'myVarName' + index;
//Send request to server
var data = {};
var i = 'ind';
var id = myVar.id;
var name = myVar.name;
data[id] = name;
data[i] = index;
$.post("script.php", data, function(data){
console.log("Server response:", data);
});
}

XMLHttpRequest sends local data twice

I'm using XMLHttpRequest's send method to upload the data that are saved in a local sqlite database, to my own website. On my website I'm running phpMyAdmin. The issue that I'm having is that the data gets transmitted to the server twice, even though the local sqlite database stores the data only once. I was wondering if anyone could help me to identify the issue. I also made sure to use XMLHttpRequest asynchronously, I still don't understand why is this happening. Any help would be greatly appreciated. Thank you.
postData: function(count) {
var surveyURL = "https://example.com/data/logging/answer.php";
var file = FileUtils.getFile("ProfD", ["ext.sqlite"]);
var dbConn = Services.storage.openDatabase(file);
var query = dbConn.createStatement("SELECT * FROM responses");
var i = 0;
while (query.step()) {
let data = {
'rowid' : query.row.rowid,
'timestamp' : query.row.timestamp,
'uid' : query.row.uid,
'warning' : query.row.warning,
'ignored' : query.row.ignored,
'domain' : query.row.domain,
'qid' : query.row.qid,
'response' : query.row.response
};
let xmlhttp = Components.classes["#mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
xmlhttp.open("POST", surveyURL, true);
xmlhttp.timeout = 5000;
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
if (/^0: Survey \d+ added/.test(xmlhttp.responseText)) {
//data was added successfully, delete the row id from local database
let matches = xmlhttp.responseText.match(/^0: Survey \d+ added \((\d+)\)/);
let rowid = matches[1];
ext.Debug.dump("Deleting row " + rowid);
try {
//commented this line out, because at first I thought this was the issue but itsn't?!
//dbConn.executeSimpleSQL("DELETE FROM responses WHERE rowid=" + rowid);
} catch(e) {
ext.Debug.dump("Error deleting row: " + e);
}
} else {
ext.Debug.dump("Remote error: " + xmlhttp.responseText);
}
}
}
try {
xmlhttp.send(ext.js.toString(data));
} catch (e) {
ext.Debug.dump("Error transmitting results: " + e);
}
query.reset();
},
testConnection: function() {
//checks whether we can reach our server
//only test the connection if we have stuff to upload
//do this asynchronously
var file = FileUtils.getFile("ProfD", ["ext.sqlite"]);
var dbConn = Services.storage.openDatabase(file);
var query=dbConn.createStatement("SELECT count(*) FROM responses");
query.executeAsync({
handleResult: function(aResultSet) {
let count = aResultSet.getNextRow().getResultByIndex(0);
ext.Debug.dump(count + " records to upload");
if (count>0) {
var testURL = "https://example.com/data/connected.php";
var xmlhttp = Components.classes["#mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
xmlhttp.open("POST", testURL, true);
xmlhttp.timeout = 5000;
var date = Date.now();
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
if (xmlhttp.responseText == date) {
ext.js.postData(count);
ext.Debug.dump("connected!");
} else {
ext.Debug.dump("not connected");
}
} else {
ext.Debug.dump("not connected");
}
}
xmlhttp.ontimeout=function() {
ext.Debug.dump("not connected! 3");
}
try {
xmlhttp.send("time=" + date);
} catch (e) {
ext.Debug.dump("Error connecting: " + e);
}
}
},
handleError: function(aError) {
ext.Debug.dump("Error: " + aError.message);
},
});
dbConn.asyncClose();
},

Unexpected end of input error with chrome.tabs.query

I've been struggling with this and have had no luck. I've included the error and most of the context around the block in question.
var successURL = 'https://www.facebook.com/connect/login_success.html';
var userFirstName = ''
var userEmail = ''
function onFacebookLogin(){
if (localStorage.getItem('accessToken')) {
chrome.tabs.query({}, function(tabs) {
for (var i = 0; i < tabs.length; i++) {
if (tabs[i].url.indexOf(successURL) !== -1) {
var params = tabs[i].url.split('#')[1];
var accessToken = params.split('&')[0];
accessToken = accessToken.split('=')[1];
localStorage.setItem('accessToken', accessToken);
chrome.tabs.remove(tabs[i].id);
console.log(accessToken);
pullSecurityToken();
findFacebookName();
}
}
});
}
}
chrome.tabs.onUpdated.addListener(onFacebookLogin);
function pullSecurityToken(){
var pointUrl = "localhost:3000/api/v1/retrieve_token_for/" + localStorage.accessToken + "/" + localStorage.securityToken;
var xhr = new XMLHttpRequest();
xhr.open("GET", pointUrl, true);
alert(JSON.parse(xhr.responseText));
}
var response = ''
function findFacebookName(){
if (localStorage.accessToken) {
var graphUrl = "https://graph.facebook.com/me?access_token=" + localStorage.accessToken;
console.log(graphUrl);
var xhr = new XMLHttpRequest();
xhr.open("GET", graphUrl, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if(xhr.status == '401'){
alert("Security Token Invalid, please check and try again.");
}
response = JSON.parse(xhr.responseText);
userFirstName = response.first_name
userEmail = response.email
console.log(response);
}
}
}
xhr.send();
}
Here's the error:
Error in response to tabs.query: SyntaxError: Unexpected end of input
at onFacebookLogin (chrome-extension://dapeikoncjikfbmjnpfhemaifpmmgibg/background.js:7:17)
Even if you use a synchronous request, you still need to send it. So add an xhr.send(); after the xhr.open inside pullSecurityToken.
As Felix Kling points out in the comments, the lack of send will directly cause your error, because the responseText property is still an empty string and such a string is not valid JSON whereas "" would be valid JSON.

Categories

Resources