Aws SDK In lambda function - javascript

I am working on lambda function and creating a method for AWS-SDK historical metric report using node, js and I am getting the following errors. Have look at a SS of error
here is my code
function getKeyByValue(object, value) {
return Object.keys(object).find(key =>
object[key] === value);
}
exports.handler = async (event) => {
const AWS = require('aws-sdk');
var connect = new AWS.Connect({ apiVersion: '2017-08-08' });
let queueARN = event.queueARN || null;
const connectInstanceId = process.env.instanceID;
let flag =0, nextToken = null;
let queueARNsObject = {}, queueARNsArray=[], queueTypeObject={};
do{
let listQueuesParams = {
InstanceId: connectInstanceId, /* required */
QueueTypes: [
"STANDARD",
],
NextToken: nextToken,
};
let listQueuesPromise = connect.listQueues(listQueuesParams).promise();
listQueuesResult = await listQueuesPromise;
// console.log(listQueuesResult);
listQueuesResult.QueueSummaryList.forEach(queue => {
if(queueARN != null){
if (queue.Arn == queueARN){
queueARNsArray = [queue.Arn];
queueARNsObject[queue.Name]= queue.Arn;
queueTypeObject[queue.QueueType]= queue.Arn;
flag = 1;
return;
}
}else{
queueARNsObject[queue.Name]= queue.Arn;
queueTypeObject[queue.QueueType]= queue.Arn;
queueARNsArray.push(queue.Arn);
nextToken = listQueuesResult.NextToken;
}
});
}while (flag=0 && nextToken != null);
const HistoricalMetricsList = [
{
Name : 'CONTACTS_HANDLED',
Unit : 'COUNT',
Statistic : 'SUM'
},
{
Name : 'CONTACTS_ABANDONED',
Unit : 'COUNT',
Statistic : 'SUM'
},
];
// Metrics params
var getHistoricalMetricsParams = {
InstanceId: connectInstanceId,
StartTime: 1592993700,
EndTime: 1593039900,
Filters: {
Channels: ["VOICE"],
Queues: queueARNsArray
},
HistoricalMetrics: HistoricalMetricsList,
Groupings: ["QUEUE"]
};
// get current metrics by queues
var getHistoricalMetricsPromise = connect
.getMetricData(getHistoricalMetricsParams)
.promise();
var getHistoricalMetricsResult = await getHistoricalMetricsPromise;
// console.log("current |||||||| 1 metrics:", JSON.stringify(getCurrentMetricsResult));
let queueMetricsArray = [];
if(getHistoricalMetricsResult.MetricResults.length){
getHistoricalMetricsResult.MetricResults.forEach(queue => {
let queueMetrics = {
"Queue_Name" : getKeyByValue(queueARNsObject ,queue.Dimensions.Queue.Arn),
"CallsHandled": queue.Collections[0].Value ,
"CallsAbanoded": queue.Collections[1].Value ,
}
queueMetricsArray.push(queueMetrics);
console.log("TYPE||||", getKeyByValue(queueTypeObject ,queue.Dimensions.Queue.Arn))
});
}else{
keys.forEach(key => {
let queueMetrics = {
"Queue_Name" : getKeyByValue(event ,queue.Dimensions.Queue.Arn),
"CONTACTS_HANDLED": 0,
"CONTACTS_ABANDONED": 0
}
queueMetricsArray.push(queueMetrics);
})
}
const response = {
responseCode: 200,
metricResults: queueMetricsArray
};
return response;
};
I don't have any idea what this is an error about. if anyone of you knows please help me to fix it Thanks. i've done the same thing with Real-Time Metric report and that is running perfectly

Related

JS API client throws 'Uncaught (in promise) TypeError: e.join is not a function' after 40 requests

Here is my code (it takes a csv file as input, does some API calls, and outputs the results as another csv file):
let allRows = [];
async function fileToLines(file) {
return new Promise((resolve, reject) => {
reader = new FileReader();
reader.onload = function (e) {
parsedLines = e.target.result.split(/\r|\n|\r\n/);
resolve(parsedLines);
};
reader.readAsText(file);
});
}
document
.getElementById('fileInput')
.addEventListener('change', async function (e) {
var file = e.target.files[0];
if (file != undefined) {
fileToLines(file).then(async id => {
console.log(id)
console.log(parsedLines)
console.log(typeof id);
var idInt = id.map(Number);
var idFiltered = id.filter(function (v) { return v !== '' });
console.log(idFiltered)
if (file != undefined) {
allRows = [];
}
for (let id of idFiltered) {
const row = await getRelease(id);
allRows.push(row);
}
download();
});
}
});
function debounce(inner, ms = 0) {
let timer = null;
let resolves = [];
return function (...args) {
// Run the function after a certain amount of time
clearTimeout(timer);
timer = setTimeout(() => {
/* Get the result of the inner function, then apply it to the resolve function of
each promise that has been created since the last time the inner function was run */
let result = inner(...args);
resolves.forEach(r => r(result));
resolves = [];
}, ms);
return new Promise(r => resolves.push(r));
};
}
const throttleFetch = debounce(fetch, 2500);
function getRelease(idFiltered) {
return throttleFetch(`https://api.discogs.com/releases/${idFiltered}`, {
headers: {
'User-Agent': '***/0.1',
'Authorization': 'key=***, secret=***',
},
}).then(response => response.json())
.then(data => {
if (data.message === 'Release not found.') {
return { error: `Release with ID ${idFiltered} does not exist` };
} else {
const id = data.id;
const delimiter = document.getElementById("delimiter").value || "|";
const artists = data.artists ? data.artists.map(artist => artist.name) : [];
const barcode = data.identifiers.filter(id => id.type === 'Barcode')
.map(barcode => barcode.value);
var formattedBarcode = barcode.join(delimiter);
const country = data.country || 'Unknown';
const genres = data.genres || [];
const formattedGenres = genres.join(delimiter);
const labels = data.labels ? data.labels.map(label => label.name) : [];
const formattedLabels = labels.join(delimiter);
const catno = data.labels ? data.labels.map(catno => catno.catno) : [];
const formattedCatNo = catno.join(delimiter);
const styles = data.styles || [];
const formattedStyles = styles.join(delimiter);
const tracklist = data.tracklist ? data.tracklist
.map(track => track.title) : [];
const formattedTracklist = tracklist.join(delimiter);
const year = data.year || 'Unknown';
const format = data.formats ? data.formats.map(format => format.name) : [];
const qty = data.formats ? data.formats.map(format => format.qty) : [];
const descriptions = data.formats ? data.formats
.map(descriptions => descriptions.descriptions) : [];
const preformattedDescriptions = descriptions.toString()
.replace('"', '""').replace(/,/g, ', ');
const formattedDescriptions = '"' + preformattedDescriptions + '"';
console.log(idFiltered,
artists,
format,
qty,
formattedDescriptions,
formattedLabels,
formattedCatNo,
country,
year,
formattedGenres,
formattedStyles,
formattedBarcode,
formattedTracklist
)
return [idFiltered,
artists,
format,
qty,
formattedDescriptions,
formattedLabels,
formattedCatNo,
country,
year,
formattedGenres,
formattedStyles,
formattedBarcode,
formattedTracklist
];
}
});
}
function download() {
const ROW_NAMES = [
"release_id",
"artist",
"format",
"qty",
"format descriptions",
"label",
"catno",
"country",
"year",
"genres",
"styles",
"barcode",
"tracklist"
];
var csvContent = "data:text/csv;charset=utf-8,"
+ ROW_NAMES + "\n" + allRows.map(e => e.join(",")).join("\n");
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "my_data.csv");
document.body.appendChild(link); // Required for Firefox
link.click();
}
The app passes tests for 5, 10, 20, or 30 lines of input, but when I try 40, I get this error:
Uncaught (in promise) TypeError: e.join is not a function
csvContent file:///D:/DOWNLOADS/CODE/***/csv.js:151
download file:///D:/DOWNLOADS/CODE/***/csv.js:151
<anonymous> file:///D:/DOWNLOADS/CODE///***/csv.js:38
async* file:///D:/DOWNLOADS/CODE/***/csv.js:20
I really don't know why that would be. Any ideas please? TIA.
Apparently I need to add more details but IDK what?

Result won't update VAR

I am trying to run a query, inside AXIOS which gets data from a 3rd party URL. Then uses some of that data to search our mongoDB database.
However it seems it won't update var total = 0
While the query below does function correctly, the return result won't allow me to set that it to the query.
Promise.all(arr.forEach( async (id,index) => {
//(CODE REMOVED JUST TO GET THIS FUNCTION TO WORK)
const search = await geoLocation.find({
'location': {
'$geoWithin': {
'$box': [
[-35.2418503, -13.5076852], [112.8656697, 129.0020486]
]
}
}}).toArray();
total = search.length;
}));
See the full code below
var array = [];
var pointarray = []
var total = 0;
areas.forEach((id,index) => {
if(id.type == "Point"){
pointarray[index] = "N"+id.id;
}else{
array[index] = "R"+id.id;
}
});
var arraySearch = "https://nominatim.openstreetmap.org/lookup?osm_ids="+array.toString()+"&polygon_geojson=1&bbox=1&format=json";
var pointSearch = "https://nominatim.openstreetmap.org/lookup?osm_ids="+pointarray.toString()+"&polygon_geojson=1&bbox=0&format=json"
const requestOne = axios.get(arraySearch);
const requestTwo = axios.get(pointSearch);
axios.all([requestOne, requestTwo])
.then(axios.spread((...responses) => {
const responseOne = responses[0]
const responseTwo = responses[1]
/*
process the responses and return in an array accordingly.
*/
return [
responseOne.data,
responseTwo.data,
];
}))
.then(arr => {
Promise.all(arr.forEach( async (id,index) => {
//const middleIndex = id[index].boundingbox.length / 2;
//const firstHalf = id[index].boundingbox.splice(0, middleIndex);
//const secondHalf = id[index].boundingbox.splice(-middleIndex);
//res.send(secondHalf[0]);
const query = [{
$match: {
location: {
$geoWithin: {$box:[[Number(firstHalf[0]),Number(firstHalf[1])],[Number(secondHalf[0]),Number(secondHalf[1])]]
}
}
}
},{
$count: 'id'
}]
const search = await geoLocation.find({
'location': {
'$geoWithin': {
'$box': [
[-35.2418503, -13.5076852], [112.8656697, 129.0020486]
]
}
}}).toArray();
total = search.length;
// total = search.length;
// const search = geoLocation.aggregate(query).toArray.length;
}));
})
.catch(errors => {
console.log("ERRORS", errors);
})
.then(function () {
res.send(total);
});

Return empty array in Fastify handler with async/await function

I'm trying to make a web3 wallet with Moralis with Fasitify in back and VueJS in front.
(I would like to say that I already do this in web client (vuejs) and everything works well!)
In my back, I fetch all the asset from user. It works, I get them all well and I can send them back to the front
But I need to process/sort the data to recover only part of it and send it to the front to avoid doing too much treatment at the front and reduce your workload.
I do that :
*handlers/token.js*
const getTokenBalances = async () => {
let userTokens;
const options = {
chain: "bsc",
address: "0x935A438C29bd810c9aBa2F3Df5144d2dF4F3c0A0",
};
userTokens = await Moralis.Web3API.account.getTokenBalances(options);
return userTokens;
};
and if I return userTokens, I had it in Postman. But now, I do something like :
const getTokenBalances = async (tokens) => {
let userTokens;
let userBalances = [];
const options = {
chain: "bsc",
address: "0x935A438C29bd810c9aBa2F3Df5144d2dF4F3c0A0",
};
userTokens = await Moralis.Web3API.account.getTokenBalances(options);
userTokens.forEach((token) => {
if (
!token.name.match(/^.*\.io/) &&
!token.name.match(/^.*\.IO/) &&
!token.name.match(/^.*\.net/) &&
!token.name.match(/^.*\.Net/) &&
!token.name.match(/^.*\.com/) &&
!token.name.match(/^.*\.org/)
) {
getTokenPair(token).then((value) => {
if (value > 2) {
checkTokenPrice(token).then((price) => {
if (price > 0.001) {
userBalances.push(token);
}
});
}
});
}
});
userBalances.sort((a, b) => {
return b.total_value_usd - a.total_value_usd;
});
return userBalances;
};
userBalances its always empty in my response in Postman (And I don't understand why ?)
The getTokenPair function :
const getTokenPair = async (token) => {
const BNBTokenAddress = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; //BNB
const options = {
token0_address: token.token_address,
token1_address: BNBTokenAddress,
exchange: "pancakeswapv2",
chain: "bsc",
};
try {
const pairAddress = await Moralis.Web3API.defi.getPairAddress(options);
let amount = 0;
//console.log("token pairAddress : " + pairAddress.pairAddress);
if (pairAddress.token1.symbol === "BUSD") {
try {
let reserve = await getPairReserves(pairAddress.pairAddress);
amount += reserve / 10 ** 18;
} catch (err) {
console.log("error getReservesBUSD : " + err);
}
}
if (pairAddress.token1.symbol === "WBNB") {
try {
let reserve = await getPairReserves(pairAddress.pairAddress);
amount += reserve / 10 ** 18;
} catch (err) {
console.log("error getReservesWBNB : " + err);
}
}
//console.log("amount : " + amount)
return amount;
} catch (err) {
console.log("error getPair : " + err);
}
};
and the checkTokenPrice function :
const checkTokenPrice = async (token) => {
let price;
const options = {
address: token.token_address,
chain: "bsc",
exchange: "PancakeSwapv2",
};
try {
const priceToken = await Moralis.Web3API.token.getTokenPrice(options);
price = priceToken.usdPrice.toFixed(7);
token.price = priceToken.usdPrice.toFixed(7);
token.balance = insertDecimal(token.balance, token.decimals);
token.total_value_usd = (token.balance * token.price).toFixed(2);
return price;
} catch (err) {
console.log("error tokenPrice : " + err);
}
};
They are await method in all the function I use so maybe there is a connection.
Thanks for you help !
**** EDIT *****
I solve my problem like this :
const getTokenBalances = async () => {
let userTokens;
let userBalances = [];
const options = {
chain: "bsc",
address: "0x935A438C29bd810c9aBa2F3Df5144d2dF4F3c0A0",
};
userTokens = await Moralis.Web3API.account.getTokenBalances(options);
for (token of userTokens) {
if (
!token.name.match(/^.*\.io/) &&
!token.name.match(/^.*\.IO/) &&
!token.name.match(/^.*\.net/) &&
!token.name.match(/^.*\.Net/) &&
!token.name.match(/^.*\.com/) &&
!token.name.match(/^.*\.org/)
) {
let value = await getTokenPair(token);
if(value > 2) {
let price = await checkTokenPrice(token);
if (price > 0.001) {
userBalances.push(token);
}
}
}
}
return userBalances;
};
Thanks for the help ! ;)

NoSuchMethodError: The method '[]' was called on null. I/flutter (23049): Receiver: null I/flutter (23049): Tried calling: []("conversationID")

I am trying to implement messages feature on my application with firebase firestore using flutter/dart language but I am having the following error.
NoSuchMethodError: The method '[]' was called on null.
I/flutter (23049): Receiver: null
I/flutter (23049): Tried calling: [] ("conversationID")
Firestore function:
"use strict";
Object.defineProperty(exports, "__esModule",{value: true});
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.onConversationCreated =
functions.firestore.document("Conversations/{conversationID}")
.onCreate((snapshot, context) => {
let data = snapshot.data();
let conversationID = context.params.conversationID;
if (data) {
let members = data.members;
for (let index = 0; index < members.length; index++) {
let currentUserID = members[index];
let remainingUserIDs = members.filter((u) => u !== currentUserID);
remainingUserIDs.forEach((m) => {
return admin.firestore().collection("Users").doc(m).get().then((_doc) => {
let userData = _doc.data();
if (userData) {
return admin.firestore().collection("Users").doc(currentUserID).collection("Conversations").doc(m).create({
"conversationID": conversationID,
"image": userData.image,
"name": userData.name,
"unseenCount": 0,
});
}
return null;
}).catch(() => { return null; });
});
}
}
return null;
});
Flutter DatabaseService Class:
Future<void> createOrGetConversartion(String _currentID, String _recepientID,
Future<void> _onSuccess(String _conversationID)) async {
var _ref = _db.collection(_conversationsCollection);
var _userConversationRef = _db
.collection(_userCollection)
.doc(_currentID)
.collection(_conversationsCollection);
try {
var conversation =
await _userConversationRef.doc(_recepientID).get();
if (conversation.data != null) {
return _onSuccess(conversation.data()["conversationID"]);
} else {
var _conversationRef = _ref.doc();
await _conversationRef.set(
{
"members": [_currentID, _recepientID],
"ownerID": _currentID,
'messages': [],
},
);
return _onSuccess(_conversationRef.id);
}
} catch (e) {
print(e);
}
}
Your null check seems incorrect here.
if (conversation.data != null) {
return _onSuccess(conversation.data()["conversationID"]);
}
You are checking for conversation.data being null or not but using conversation.data() after null check. This only checks for the method is existing or not.
Instead of this, you should be doing something like this.
final data = conversation.data();
if (data != null) {
return _onSuccess(data["conversationID"]);
}

How to bypass jest setTimeout error of 5000ms by managing promises (Async and Await)

I wrote an Async/Await function to return promises for drivers report and analysis.
I have three different promise API files I extracted details from to do my analysis. However running test ith jest I get the error
Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error:
I have refactored my code more than three times in two days but the error returns.
I will like to know how to manage my promises, perhaps there is something am not doing well and I am keen on this for optimization.
Is there a way to manage the promises in the code below to bypass the jest error?
any other suggestion will be highly appreciated.
NB: sorry I have post all the code for better insight.
code
const { getTrips } = require('api');
const { getDriver } = require('api')
const { getVehicle } = require('api')
/**
* This function should return the data for drivers in the specified format
*
* Question 4
*
* #returns {any} Driver report data
*/
async function driverReport() {
// Your code goes here
let trip = await getTrips()
trip = trip.map(item => {
item.billedAmount = parseFloat(item.billedAmount.toString().replace(',', '')).toFixed(2);
return item;
})
let getId = trip.reduce((user, cur) => {
user[cur.driverID] ? user[cur.driverID] = user[cur.driverID] + 1 : user[cur.driverID] = 1
return user
}, {})
// console.log(getId)
let mapId = Object.keys(getId)
// console.log(mapId)
let eachTripSummary = mapId.reduce((acc, cur) => {
let singleTrip = trip.filter(item => item.driverID == cur)
acc.push(singleTrip)
return acc
}, [])
// eachTripSummary = eachTripSummary[0]
// console.log(eachTripSummary)
// console.log(trip)
let reducedReport = eachTripSummary.reduce(async(acc, cur) =>{
acc = await acc
// console.log(acc)
let user = {}
let cash = cur.filter(item => item.isCash == true)
// console.log(cash.length)
let nonCash = cur.filter(item => item.isCash == false)
let driverSummary = await getDriverSummary(cur[0]['driverID'])
let trips = []
let customer = {}
cur[0].user ? (customer['user'] = cur[0]['user']['name'], customer['created'] = cur[0]['created'], customer['pickup'] = cur[0]['pickup']['address'],
customer['destination'] = cur[0]['destination']['address'], customer['billed'] = cur[0]['billedAmount'], customer['isCash'] = cur[0]['isCash']) : false
trips.push(customer)
let vehicles = []
if(driverSummary == undefined){
// console.log(cur)
user = {
id: cur[0]['driverID'],
vehicles: vehicles,
noOfCashTrips: cash.length,
noOfNonCashTrips: nonCash.length,
noOfTrips: cur.length,
trips: trips
}
acc.push(user)
// console.log(user)
return acc
}
let driverInfo = driverSummary[0]
let vehicleInfo = driverSummary[1]
let { name, phone } = driverInfo
let { plate, manufacturer } = vehicleInfo[0]
// console.log(plate)
let vpm = {
plate,
manufacturer
}
vehicles.push(vpm)
// console.log(cash.length)
user ={
fulName: name,
phone,
id: cur[0]['driverID'],
vehicles: vehicles,
noOfCashTrips: cash.length,
noOfNonCashTrips: nonCash.length,
noOfTrips: cur.length,
trips: trips
}
acc.push(user)
// console.log(acc)
return acc
}, [])
// reducedReport.then(data =>{console.log(data)})
return reducedReport
}
async function getDriverSummary(param) {
let driverDetails = await getDriver(param)
.then(data => {return data}).catch(err => {return err})
// console.log(driverDetails)
let vehicleDetails;
let { vehicleID } = driverDetails
if(driverDetails != "Error" & vehicleID != undefined){
// console.log(vehicleID)
vehicleDetails = vehicleID.map(async item => {
let vehicleSummary = getVehicle(item)
return vehicleSummary
})
// console.log(await vehicleDetails)
return await Promise.all([driverDetails, vehicleDetails])
}
}
driverReport().then(data => {
console.log(data)
})
module.exports = driverReport;
Use jest.setTimeout(30000); to increase the timeout. It will increase the timeout globally.
// jest.config.js
module.exports = {
setupTestFrameworkScriptFile: './jest.setup.js'
}
// jest.setup.js
jest.setTimeout(30000)
Or you can use user test example like this
describe("...", () => {
test(`...`, async () => {
...
}, 30000);
});

Categories

Resources