How can I push array-data one scope higher - javascript

I need the data from time_array outside of the first loop. When I console.log(time_array) inside the first loop I get the following results:
MongoClient.connect(CONNECTION_URL, { useNewUrlParser: true }, function (err, db) {
if (err) throw err;
var db = db.db("coinlib");
const userid = '5de2c1be7224c00e6723b7e3';
const time_array = [];
db.collection("users").findOne({ _id: ObjectID(userid) }, function (err, portfolio) {
if (err) throw err;
const portfolio_length = portfolio.portfolio.length;
for (let i = 0; i < portfolio_length; i++) {
db.collection("coin-data-24h").findOne({ ticker: portfolio.portfolio[i].ticker }, function (err, coin_data_24h) {
if (err) throw err;
for (let ii = 0; ii < portfolio.portfolio[i].node_count; ii++) {
// Filter data between startDate and endDate
const startDate = new Date(portfolio.portfolio[i].nodes[ii].online_since);
const endDate = new Date();
const dataset = coin_data_24h.dataset;
let result = dataset.filter(item => new Date(item.timestamp) >= startDate && new Date(item.timestamp) <= endDate)
// Create array and fill it with 0
const array_with_zeros = Array.from(Array(3), () => 0)
// Return 3 results only
const array_with_data = result.slice(0, 3);
// How many results are in there
const length_array_with_data = array_with_data.length;
const start_index = 3 - length_array_with_data;
for (let i = 0; i < length_array_with_data; i++) {
array_with_zeros[start_index + i] = array_with_data[i].usd_price;
}
time_array.push(array_with_zeros);
} // for end
console.log(time_array);
}) // db end
} // for end
console.log(time_array);
}); // db end
}); // Mongo end
Result:
[ [ 5.619693750948361, 12.291785200236262, 57.45995830212961 ],
[ 19.577872231080086, 36.00637519615492, 24.425419908972522 ],
[ 19.577872231080086, 36.00637519615492, 24.425419908972522 ] ]
[ [ 5.619693750948361, 12.291785200236262, 57.45995830212961 ],
[ 19.577872231080086, 36.00637519615492, 24.425419908972522 ],
[ 19.577872231080086, 36.00637519615492, 24.425419908972522 ],
[ 0.7144408839408483, 2.256984583694044, 0.2710203249491058 ] ]
When I console.log(time_array) outside of the first loop, I get an empty array.
Please tell me why? I defined time_array outside of the loops, so it should work. Thank you so much.

Related

How to append another API call to an async function for inventory report

Can you help on coding this consolidated report "properly"? I am not fluent on Promises yet so the existing code looks like callback hell.
I have managed to get the Resources of each API Gateway, now I have to append the last API call (getMethod) and run it synchronously for the report to be accurate. We are currently trying to evaluate the security of our API Gateways.
Thank you in advance!
const AWS = require('aws-sdk');
var apigateway = new AWS.APIGateway();
exports.handler = (event) => {
var params = {
limit: '500',
position: null
};
apigateway.getRestApis(params, function (err, data) {
if (err) console.log(err, err.stack);
let apiData = data.items;
let apiLength = data.items.length;
var count = 1;
const delay = async (ms = 1000) =>
new Promise(resolve => setTimeout(resolve, ms))
async function getResources() {
for (let i = 0; i < apiData.length; i++) {
var params = {
restApiId: apiData[i].id,
limit: 500,
position: null,
};
var apiId = apiData[i].id;
var apiName = apiData[i].name;
var endpointType = apiData[i].endpointConfiguration.types[0];
var canExecuteDataEndpoint = apiData[i].disableExecuteApiEndpoint;
apigateway.getResources(params, function (err, data) {
var resources = data.items;
var methods = ["GET", "PATCH", "PUT", "OPTIONS", "DELETE", "POST", "ANY"];
if (err) console.log(err, err.stack);
else {
//var methodCount = 1;
for (let j = 0; j < resources.length; j++) {
var resource = resources[j];
if (resources[j].hasOwnProperty("resourceMethods")) {
for (let k = 0; k < methods.length; k++) {
if (resource.resourceMethods.hasOwnProperty(methods[k])) {
var resourceId = resources[j].id;
var resourcePath = resources[j].path
var params = {
httpMethod: methods[k],
resourceId: resources[j].id,
restApiId: apiId
};
console.log(resourceId, resourcePath, params.httpMethod);
/*apigateway.getMethod(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else {
if (data.authorizationType == "NONE" && data.apiKeyRequired == false) {
//console.log(apiId, apiName, endpointType, canExecuteDataEndpoint, resourceId, resourcePath, data.httpMethod, data.authorizationType, data.apiKeyRequired);
//console.log(data.httpMethod, data.authorizationType, data.apiKeyRequired);
console.log(resourceId, resourcePath, params.httpMethod);
}
}
});*/
}
}
}
}
}
});
count++;
await delay(1000);
}
}
getResources();
});
};

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);
});

how to export this value in nodejs

I'm trying to get the amount received from the request by going to a list and then trying to export it to another file, but I'm having trouble doing this because I tried several ways to pass the list as return and it didn't work.
const moment = require("moment");
const sslChecker = require("ssl-checker");
const express = require("express");
//const dominios = require('./server');
var dominios = [
"api-prd.koerich.com.br",
"api-prd.reservapto.com.br",
"c.btg360.com.br",
"compassouol.com",
"gmfy.compasso.com.br",
"webqplus.cbn.com.bo",
"webqplus.cerchile.cl",
"webqplus.cervepar.com.py",
"webqplus.fnc.com.uy",
"webqplus.quilmes.com.ar",
"www.efurukawa.com",
];
var get_domain = dominios;
for (var i = 0; i < get_domain.length; i++) {
sslChecker(get_domain[i])
.then((certdata) => {
var startdate = new Date(certdata.validFrom);
var enddate = new Date(certdata.validTo);
var certstart = moment(startdate);
var certend = moment(enddate);
var ssldata = [
{
domain: get_domain,
issued: certstart.format("LLLL"),
expires: certend.format("LLLL"),
daysleft: certdata.daysRemaining,
},
];
var data = JSON.parse(certdata.daysRemaining);
var nomes = (certdata.validFor[0]);
var lista = [];
lista.push(data);
lista.push(nomes);
console.log(lista); //get this values
})
.catch((err) => {
console.log(err);
});
}
//module.exports = lista; //export here
console.log:
async function getList() {
mondongo = [];
var dominios = [
"api-prd.koerich.com.br",
"api-prd.reservapto.com.br",
"c.btg360.com.br",
"compassouol.com",
"gmfy.compasso.com.br",
"webqplus.cbn.com.bo",
"webqplus.cerchile.cl",
"webqplus.cervepar.com.py",
"webqplus.fnc.com.uy",
"webqplus.quilmes.com.ar",
"www.efurukawa.com",
]
try {
for (var i = 2; i < domains.length; i++) {
mondongo.push(
sslChecker(domains[i])
.then((certdata) => {
var startdate = new Date(certdata.validFrom);
var enddate = new Date(certdata.validTo);
var certstart = moment(startdate);
var certend = moment(enddate);
var ssldata = [
{
domain: domains,
issued: certstart.format("LLLL"),
expires: certend.format("LLLL"),
daysleft: certdata.daysRemaining,
},
];
var data = certdata.daysRemaining;
var nome = certdata.validFor[0];
var lista = [];
lista.push(nome);
lista.push(data);
return lista;
})
.catch((err) => {
//console.log(err);
})
);
}
}
catch (error) {
console.log(error);
}
var arroz = await Promise.all(mondongo);
return arroz;
}
return:
create a function and use the async await methods.

How to return Boolean properly in different NodeJS files?

So I have files inside the following folder:
app/controller/token.js
app/controller/news.js
token.js:
"use strict";
var connection = require("../con");
exports.isTokenExists = function(token) {
var checkToken = "SELECT COUNT(`id`) AS 'total' FROM `user` WHERE `token` = '" + token + "'";
var isExists = false;
var count;
var checkResult;
connection.query(checkToken, function(error, rows) {
if (!error) {
checkResult = JSON.parse(JSON.stringify(rows));
for (var i = 0; i < checkResult.length; i++) {
var row = rows[i];
count = row.total;
}
if (count > 0) {
isExists = true;
}
}
});
return isExists;
};
news.js:
"use strict";
var response = require("../response/responses");
var connection = require("../con");
var getToken = require("./token");
exports.news = function(req, res) {
response.send(false, "News API", null, res);
};
exports.allNews = function(req, res) {
var checkTokenExists = getToken.isTokenExists("75d12cc4dc07608d5b87a6cba33cac056df1239c");
if (checkTokenExists) {
var allNewsQuery = "SELECT a.`id`, b.`title` AS `category`, a.`title`, a.`description`, a.`content`, a.`image`, a.`created_date` FROM `news` AS a LEFT JOIN `news_category` AS b ON a.`id_news_category` = b.`id` ORDER BY `created_date` DESC LIMIT 20";
connection.query(allNewsQuery, function(error, rows) {
if (error) {
response.send(true, "" + error, null, res);
} else {
var data = [];
var newsData = JSON.parse(JSON.stringify(rows));
for (var i = 0; i < newsData.length; i++) {
var row = rows[i];
data[i] = {
id: row.id,
idCategory: row.idCategory,
category: row.category,
title: row.title,
description: row.description,
image: row.image,
createdDate: row.created_date
};
}
response.send(false, "News is not empty", data, res);
}
});
} else {
response.send(true, "Error: Token not found", checkTokenExists, res);
}
};
I always getting false value from isTokenExists meanwhile the token is exists in the table.
How do I get true response if the token is exist and how do I get false response if the token is not exists in table?
Any help will be much appreciated.
Regards.
The issue here is that connection.query accepts a callback, but the rest of your code will move passed that without awaiting the result, which is why your isExists always returns false. You can fix this by encapsulating the query with a Promise like this:
"use strict";
const connection = require("../con");
exports.isTokenExists = async function(token) {
const checkToken = "SELECT COUNT(`id`) AS 'total' FROM `user` WHERE `token` = ?";
return new Promise((resolve, reject) => {
connection.query(checkToken, token, function (error, results) {
if (error) return reject(error);
return resolve(results.length > 0);
});
});
};
I also simplified the logic in the callback a bit.
Then, in news.js await the result like this:
exports.allNews = async function(req, res) {
getToken.isTokenExists("75d12cc4dc07608d5b87a6cba33cac056df1239c")
.then(result => {
if (result === true) {
//place your code for handling if the token exists here
}
else {
//place your code for handling if the token does not exist
}
})
.catch(err => {
//handle error
});
}
You are missing async / await concept. You need to wait until your query executes.
1) Write a promise function
export.getCount = function(query) {
return new Promise((res, rej) => {
let count = 0;
connection.query(checkToken, function(error, rows) {
if (!error) {
checkResult = JSON.parse(JSON.stringify(rows));
for (var i = 0; i < checkResult.length; i++) {
var row = rows[i];
count = row.total;
}
}
return res(count);
})
}
2) Write async function which supports await operations
exports.isTokenExists = async function(token) {
var query = "SELECT COUNT(`id`) AS 'total' FROM `user` WHERE `token` = '" + token + "'";
let count = await getCount(query)
return count > 0; // Returns true if count is > 0
};

Javascript object not appending new attribute

I have this function, where I retrieve an array of objects, I then have a for loop to loop through the objects, and append an index or ind attribute to it:
module.exports.getCustomers = async (req, res) => {
let customers = await Customers.find({}, { "_id": 1 });
for (var i = 0; i < customers.length; i++) {
customers[i].ind = i;
}
console.log(customers)
}
but when I run this, the data is returned as
[
{ _id: ... },
{ _id: ... },
...
]
instead of:
[
{_id: ..., ind: 0},
{_id: ..., ind: 1},
...
]
Please how do I fix this
change your for and turn it into a map
module.exports.getCustomers = async (req, res) => {
let customers = await Customers.find({}, { "_id": 1 });
let mappedCustomers = customers.map((customer, index) => {
customer['ind'] = index;
return customer;
});
console.log(mappedCustomers);
return mappedCustomers;
}
or instead returning the customer, you can create a completly new customer.
let mappedCustomers = customers.map((customer, index) => {
return {...customer, ind: index};
});
It looks like your objects are freezed, idk what library you are using to fetch those items from your data source, but you can read about object freezing here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
Try copying the values over to the individual target objects with Object.assign.
module.exports.getCustomers = async(req, res) => {
let customers = await Customers.find({}, {
"_id": 1
});
for (var i = 0; i < customers.length; i++) {
Object.assign(customers[i], {
ind: i
});
}
console.log(customers);
}
I finally solved it. I think mongoose was messing with it. But adding ._doc seems to have fixed it
for (let i = 0; i < customers.length; i++) {
let customer = customers[i],
customer._doc = {
...customer._doc,
index: i
};
}

Categories

Resources