AWS Lambda - Only getting answer after the second test trigger - javascript

I'm developing an AWS Lambda in TypeScript that uses Axios to get data from an API and that data will be filtered and be put into a dynamoDb.
The code looks as follows:
export {};
const axios = require("axios");
const AWS = require('aws-sdk');
exports.handler = async (event: any) => {
const shuttleDB = new AWS.DynamoDB.DocumentClient();
const startDate = "2021-08-16";
const endDate = "2021-08-16";
const startTime = "16:00:00";
const endTime = "17:00:00";
const response = await axios.post('URL', {
data:{
"von": startDate+"T"+startTime,
"bis": endDate+"T"+endTime
}}, {
headers: {
'x-rs-api-key': KEY
}
}
);
const params = response.data.data;
const putPromise = params.map(async(elem: object) => {
delete elem.feat1;
delete elem.feat2;
delete elem.feat3;
delete elem.feat4;
delete elem.feat5;
const paramsDynamoDB = {
TableName: String(process.env.TABLE_NAME),
Item: elem
}
shuttleDB.put(paramsDynamoDB).promise();
});
await Promise.all(putPromise);
};
This all works kind of fine. If the test button gets pushed the first time, everything seems fine and is working. E.g. I received all the console.logs during developing but the data is not put into the db.
With the second try it is the same output but the data is successfully put into the Db.
Any ideas regarding this issue? How can I solve this problem and have the data put into the Db after the first try?
Thanks in advance!

you need to return the promise from the db call -
return shuttleDB.put(paramsDynamoDB).promise();
also, Promise.all will complete early if any call fails (compared to Promise.allSettled), so it may be worth logging out any errors that may be happening too.
Better still, take a look at transactWrite - https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#transactWrite-property to ensure all or nothing gets written

Related

.sendSignedTransaction() Not sending Tx

Bit of context; this was working fine on Goerli just a few days a go but the script now works intermittently. At the moment im thinking its down to one of the following:
Node issue - currently using infura and have tried changing it across other public RPCS but didn't work any better
Web3 issue - not sure if something is now outdated
Nonce issue with wallets, not sure if there is something obvious in the code here that is causing my Txs to get stuck and as such never return a receipt
For some reason this was all working fine last night after having not worked all day. Bit stuck as to what i could be doing wrong tbh. The logic is that based on a mempool tx, the sendTx function is invoked with the 'targetAddress' param which contains all the necessary objects to replicate the tx which i am tracking.
Tx.js:
const Web3 = require('web3');
const Tx = require('ethereumjs-tx');
process.removeAllListeners('warning');
require('dotenv').config();
const INFURA_URL_TESTNET = process.env.INFURA_URL_TESTNET;
const web3 = new Web3(INFURA_URL_TESTNET);
const BN = web3.utils.BN;
// Tx details:
const sendTx = async (targetAddress) => {
const address = targetAddress.address;
const ethAmmount = targetAddress.value;
const data = targetAddress.input;
const gasLimit = targetAddress.gas;
//const gasPrice = targetAddress.gasPrice - web3.utils.toWei('1', 'gwei');
const maxFeePerGas = targetAddress.maxFeePerGas //- 1000000;
const maxPriorityFeePerGas = targetAddress.maxPriorityFeePerGas //- 1000000;
const privKey = targetAddress.privKey;
const from = targetAddress.from;
const _txCount = await web3.eth.getTransactionCount(from);
const createTransaction = await web3.eth.accounts.signTransaction(
{ to: address,
from: from,
data: data,
gas: gasLimit,
value: ethAmmount,
nonce: _txCount,
maxFeePerGas: maxFeePerGas,
maxPriorityFeePerGas: maxPriorityFeePerGas,
},
privKey,
);
// Send Tx and Wait for Receipt
const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction);
//const transaction = await web3.eth.getTransaction(createReceipt.transactionHash);
console.log(`Tx successful with hash: ${createReceipt.transactionHash}`);
};
module.exports = {sendTx};
The code stops at the await .sendSignedTx and doesn't return a receipt. As i said, this does work exactly as expected sometimes and i can figure out why sometimes it works and sometimes it doesn't?
Thanks everyone!
Since you are using web3js, you have to handle the event promise chain when calling sendSignedTransaction and log all the payloads. That will tell you the reason for it not being broadcast. Could be a network error, gas issue, maybe nonce .e.t.c.
See https://web3js.readthedocs.io/en/v1.2.11/callbacks-promises-events.html#callbacks-promises-events

Data not returning from async function with database connection

The goal is to call a function from my main script that connects to a database, reads a document from it, stores pieces of that document in a new object, and returns that object to my main script. The problem is I cannot get it all to work together. If I try one thing, I get the results but my program locks up. If I try something else I get undefined results.
Long story short, how do I open a database and retrieve something from it to another script.
The program is a quiz site and I want to return the quiz name and the questions.
const myDb = require('./app.js');
var myData = myDb.fun((myData) => {
console.log(myData.quizName);
});
Here is the script that tries to open the database and find the data
const { MongoClient } = require("mongodb");
const {mongoClient} = require("mongodb");
const uri = connection uri goes here but my name is hard coded into it at the moment so I removed for privacy
const client = new MongoClient(uri);
const fun = async (cback) => {
try {
await client.connect();
const database = client.db('Quiz-Capstone');
const quizzes = database.collection('Quiz');
const query = {quizName: "CIS01"};
const options = {
sort: {},
projection: {}
};
const quiz = await quizzes.findOne(query, options);
var quizObject = {
quizName: quiz.quizName,
quizQuestions: quiz.quizQuestions
}
//console.log(testOb);
} finally {
await client.close();
cback(quizObject);
}
}
fun().catch(console.dir);
module.exports = {
fun: fun
}
UPDATE: Still stuck. I have read several different threads here about asynchronous calls and callbacks but I cannot get my function located in one file to return a value to the caller located in another file.

Fetch api return same data always

Every time one of my button is clicked, I trigger a call to the adviceslip API to get an advice data. I expect the payload to vary. But the exact same data is returned after each call.
I've tried to call getAdvice function as a callback but it didn't work.
Am I missing something?
'use strict'
const title = document.querySelector('.advice-title')
const desc = document.querySelector('.advice-text')
const btn = document.querySelector('.btn')
const getAdvice = async () =>{
try{
const response = await fetch('https://api.adviceslip.com/advice');
if (!response.ok){
throw new Error('Api connection problem')
}
const responseJson = await response.json();
const data = responseJson.slip;
const id = `ADVICE #${data.id}`;
const advice = `"${data.advice}"`;
title.textContent = id;
desc.textContent = advice;
}
catch (e) {
console.error(e)
}
}
btn.addEventListener('click', () => {
getAdvice()
})
There appears to be an issue with caching where multiple requests closely spaced in time from a web page will cause the same result to come back. If I add a uniquely changing value to the URL to defeat caching like this:
const response = await fetch('https://api.adviceslip.com/advice?t=' + Math.random());
Then, I get a unique response every time.
I experimented with sending various headers to disable caching instead of the t=xxx hack, but those headers trigger a CORs error and the fetch() does not succeed because custom headers like this don't pass the test for a "simple" CORS request and thus require pre-flight which the target site does not support. So, the ?t=xxx where xxx is different on each request seems to do the trick.
I found this and it worked for me. Add
const response = await fetch("https://api.adviceslip.com/advice", { cache: "no-cache" });

Google Apps Script Hoisting and ReferenceError

I've been trying to find an answer to this for a few weeks, but couldn't quite do this, so I decided to ask.
I sometimes get this error:
ReferenceError: <SomeObject> is not defined
...whereas I know for sure that it is. The problem is that the object is located in a different file, so if I call the object from that file (or maybe even a third file), the code does work.
I believe this must have to do with how hoisting works, meaning I'm trying to call an object before it's declared.
But then how does it work exactly when you have different files?
Here's an example:
If I have the following code in one file and I run getID(), it works:
const SomeAPI = (function () {
const _auth = new WeakMap();
const _url = new WeakMap();
class SomeAPI {
constructor(url, user = DEFAULT_USER, pwd = DEFAULT_PWD) {
_url.set(this, url);
_auth.set(this, Utilities.base64Encode(`${user}:${pwd}`));
}
async fetch() {
const headers = {
Authorization: `Basic ${_auth.get(this)}`,
};
const options = {
headers,
};
const response = await UrlFetchApp.fetch(_url.get(this), options);
const data = JSON.parse(response);
return data;
}
}
return SomeAPI;
})();
const LIST_DATA = (async () => await getListData())();
async function getListData() {
const response = await new SomeAPI(ALL_SETTINGS['List API URL']).fetch();
return Array.isArray(response) ? response[0] : response;
}
const getID = async () => {
const listData = await LIST_DATA;
const listId = listData.list_id;
const id = {
sheetId: SpreadsheetApp.getActive().getId(),
listId
};
console.log(id);
return id;
};
However, if I move LIST_DATA, getListData() and getID() to a different file, I get:
ReferenceError: SomeAPI is not defined
Overall the project is composed of 17 different files.
All help is greatly appreciated!
Per the comment by #Cooper to your question, moving the file up works. I had the same problem with a class I created. I moved the file with the class to the top and it solved my problem.

Can not get AEC model Data in Autodesk Forge

i try to activate Revit Levels and 2D Minimap extension in autodesk forge viewer, but can not get AEC Model Data. I got this worning`
i tried to get AEC data with this code
const url = window.location.search;
console.log(url);
const svf_path = `${url.replace("?", "/storage/").replace(/%20/g, " ")}`;
Autodesk.Viewing.endpoint.getItemApi = (endpoint, derivativeUrn, api) => {
return svf_path;
};
Autodesk.Viewing.Initializer(options, async () => {
const paths = svf_path.split("/");
const [dest, svf_dir] = [paths[2], paths[3]];
const url = `/api/viewer/dest/${dest}/svf/${svf_dir}/manifest`;
const response = await fetch(url);
const manifest = await response.json();
const init_div = document.getElementById("init_div");
viewer = new Autodesk.Viewing.GuiViewer3D(init_div, config3d);
const viewerDocument = new Autodesk.Viewing.Document(manifest);
const viewable = viewerDocument.getRoot().getDefaultGeometry();
viewer.start();
await viewerDocument.downloadAecModelData();
viewer.loadDocumentNode(viewerDocument, viewable)
.then(function (result) {
Autodesk.Viewing.Document.getAecModelData(viewable);
})
});
wats wrong in my code?
The warning comes from the BubbleNode.prototype.getAecModelData method. You are not calling it in your code but it's possible that it's being called by the LevelsExtension itself. Try configuring the extension so that it doesn't detect the AEC data automatically by passing in { autoDetectAecModelData: false } as the extension options.
Btw. to debug the issue on your side, you can also try getting the non-minified version of viewer3D.js, put a breakpoint to where the warning is being logged, and see the call stack when the breakpoint is hit.

Categories