values get undefined after then of promise nodejs - node.js

I'm facing a problem with my code... I make a query to my DB to check if a mac address of a array of macs is on the DB. If I have any result I return the count of macs in my DB and if is > 0 then I don't add nothing cause the mac already is listed, but if my result.count = 0 then I will add a new record.
My new record just have the mac address. For this I'm trying:
var countRepetidos = 0
var countPromises = []
if (obj.data.list != {} && obj.data.list.length > 0) {
var aux = obj.data["list"]
countRepetidos = 0
for (var i = 0; i < aux.length; i++) {
countPromises.push(Database.Probing.getMacAdress(aux[i]).then(function(data) {
console.log("probing countPromises aux[i] ", aux[i])
if (data.count > 0) {
countRepetidos += 1
} else {
Database.Probing.addMac(aux[i])
}
return Promise.resolve()
}))
}
Promise.all(countPromises).then(() => {
dataRepeated = [obj.data.stats.since, countRepetidos]
listaRepeated.push(dataRepeated)
console.log("probing listaRepeated --> ", listaRepeated)
if (listaRepeated != [] && (listaRepeated[0][0] != undefined && listaRepeated[0][1] != undefined)) {
Database.Probing.getLastTimestamp("probing_repeated", device.id).then(function(data) {
var lastTimestamp = data.date_part
console.log('probing lastTimestamp ', lastTimestamp * 1000)
if (lastTimestamp != listaRepeated[0][0] / 1000) {
Controllers.Agregate.agregateData("probing_repeated", 5 * 60, listaRepeated, dbHistConnectionString, device.id, device.network_id, device.organization_id, ["time", "clients"])
}
})
}
})
}
The problem is after the then of Database.Probing.getMacAddress my aux[i] gets undefined and I need this value to insert into my DB.
Anyone can help?

You need to preserve the value of i. You can do this way:
for (var i = 0; i < aux.length; i++) {
(function(i) {
countPromises.push(
Database.Probing.getMacAdress(aux[i]).then(function(data) {
console.log("probing countPromises aux[i] ", aux[i])
if (data.count > 0) {
countRepetidos += 1
} else {
Database.Probing.addMac(aux[i])
}
return Promise.resolve()
}))
})(i)
}
Edit 1: As suggested by #lain, use let over var
for (let i = 0; i < aux.length; i++) {}

Related

How to display text next to ascii art (in terminal) in NodeJS?

I would like to display some ascii art in this format:
_,-, Name: Powerful Axe
T_ | Rarity: Yellow Rarity (77.5)
||`-' Attack: 100
|| Defense: 100
|| Speed: 100
~~ Gold Value: 10
an axe that is really rare
I want it in a column layout, kind of like neofetch does, but in NodeJS.
I get all this data from a json file, and I am using the following function to format and color the key pair type values:
const chalk = require('chalk')
function keyValue(key, value) {
return chalk.green(key) + ": " + chalk.yellow(value)
}
This all needs to be in the terminal, and preferably not using node-curses or blessed.
I found a very inefficient and bloated solution:
function print2MultiLine(string, string2) {
var arr1 = string.split("\n");
var arr2 = string2.split("\n");
if (arr1.length > arr2.length) {
while (arr1.length > arr2.length) {
arr2.push("");
}
} else if (arr1.length < arr2.length) {
while (arr1.length < arr2.length) {
arr1.push("");
}
}
var longestLine = 0;
for (let i = 0; i < arr1.length; i++) {
if (arr1[i].length > longestLine) {
longestLine = arr1[i].length;
}
}
for (let i = 0; i < arr1.length; i++) {
while (arr1[i].length < longestLine) {
arr1[i] += " ";
}
}
for (let i = 0; i < arr1.length; i++) {
console.log(arr1[i] + " " + arr2[i]);
}
}
if you like comments:
function print2MultiLine(string, string2) {
// for each line in each string, print it out 3 spaces away from the other
var arr1 = string.split("\n");
var arr2 = string2.split("\n");
// if one string is longer than the other, make the shorter one the length of the longer one
if (arr1.length > arr2.length) {
while (arr1.length > arr2.length) {
arr2.push("");
}
} else if (arr1.length < arr2.length) {
while (arr1.length < arr2.length) {
arr1.push("");
}
}
// get the length of the longest line in arr1
var longestLine = 0;
for (let i = 0; i < arr1.length; i++) {
if (arr1[i].length > longestLine) {
longestLine = arr1[i].length;
}
}
// make all other lines in arr1 the length of the longest line
for (let i = 0; i < arr1.length; i++) {
while (arr1[i].length < longestLine) {
arr1[i] += " ";
}
}
// print out the strings
for (let i = 0; i < arr1.length; i++) {
console.log(arr1[i] + " " + arr2[i]);
}
}
Preview:

Why break statement does not work in else loop, is there any alternative to this?

Inside nested for loop I am using if/else if else condition. When if and else if condition are false, final else condition is running as expected but as it is in for loop instead of just running once it is running multiple times. What changes do i need to make to make else condition work only once?
Here is my code
productCodes: string[] = [],
vehicleType: string[] = [],
for (var i = 0; i < urls.length; i++) {
return https.get(urls[i], res => {
res.on('data', function(chunk) {
json += chunk;
});
res.on('end', function() {
var result = JSON.parse(json);
for (var i = 0; i < result.length; i++) {
for (var j = 0; j < result[i].products.length; j++) {
if (productCodes.length !== 0 && productCodes !== undefined) {
for (var k = 0; k < productCodes.length; k++) {
if (result[i].products[j].productCode == productCodes[k]) {
console.log(
'Product Codes: ' +
result[i].products[j].productCode
);
}
}
} else if (
vehicleType.length !== 0 &&
vehicleType !== undefined
) {
for (var k = 0; k < vehicleType.length; k++) {
if (result[i].products[j].productType == vehicleType[k]) {
console.log(
'Product Codes: ' +
result[i].products[j].productCode
);
}
}
} else {
console.log('No data');
break; ------------------------> HERE
}
}
}
});
});
}
```
If the loops are to cease after you encounter your last "else" statement I would recommend breaking them, if necessary using labels.
Here is a related question! It's for java, but the syntax is similar.
If it is just about only displaying the message once, consider just setting a boolean, then asking for it after the loops have concluded, and if true log the message.
EDIT: To expand my answer for your edit, I am not sure what exactly your desired behaviour would be, but chances are you want to break a loop deeper down than the topmost one. break; will break the topmost loop, in your case I believe that would be
for (var j = 0; j < result[i].products.length; j++)
But not the loop directly above that, iterating over this loop all over again.
Try assigning a label to the loop you want to break further down, and then break that one specifically.
EDIT 2:
I've modified your code to include the example of labels. That way, you can break whichever loop you actually want to end. Just comment the appropriate break back in. Hope this is helpful!
productCodes: string[] = [],
vehicleType: string[] = [],
outer1:
for (var i = 0; i < urls.length; i++)
{
return https.get(urls[i], res =>
{
res.on('data', function(chunk)
{
json += chunk;
});
res.on('end', function()
{
var result = JSON.parse(json);
middle1:
for (var i = 0; i < result.length; i++)
{
for (var j = 0; j < result[i].products.length; j++)
{
if (productCodes.length !== 0 && productCodes !== undefined)
{
for (var k = 0; k < productCodes.length; k++)
{
if (result[i].products[j].productCode == productCodes[k])
{
console.log(
'Product Codes: ' +
result[i].products[j].productCode
);
}
}
}
else if (
vehicleType.length !== 0 &&
vehicleType !== undefined
)
{
for (var k = 0; k < vehicleType.length; k++)
{
if (result[i].products[j].productType == vehicleType[k])
{
console.log(
'Product Codes: ' +
result[i].products[j].productCode
);
}
}
}
else
{
console.log('No data');
//break outer1;
//break middle1;
//break;
-- -- -- -- -- -- -- -- -- -- -- -- > HERE
}
}
}
});
});
}
As an additional note, nested labled loops or blocks like these are fairly uncommon due to the tendency to be able to resolve loops things in their own individual functions and then simply call those. I'd advise you to take a look at the java-based answer I linked above if you wanted to look into that.

How to verify a document from QLDB in Node.js?

I'm trying to verify a document from QLDB using nodejs. I have been following the Java verification example as much as I can, but I'm unable to calculate the same digest as stored on the ledger.
This is the code I have come up with. I query the proof and block hash from QLDB and then try to calculate digest in the same way as in Java example. But after concatinating the two hashes and calculating the new hash from the result I get the wrong output from crypto.createHash('sha256').update(c).digest("base64"). I have also tried using "base64" instead of "hex" with different, but also wrong result.
const rBlock = makeReader(res.Revision.IonText);
var block = [];
rBlock.next();
rBlock.stepIn();
rBlock.next();
while (rBlock.next() != null) {
if (rBlock.fieldName() == 'hash') {
block.push(Buffer.from(rBlock.byteValue()).toString('hex'));
}
}
console.log(block);
var proof = [];
const rProof = makeReader(res.Proof.IonText);
rProof.next();
rProof.stepIn();
while (rProof.next() != null) {
proof.push(Buffer.from(rProof.byteValue()).toString('hex'));
}
var ph = block[0];
var c;
for (var i = 0; i < proof.length; i++) {
console.log(proof[i])
for (var j = 0; j < ph.length; j++) {
if (parseInt(ph[j]) > parseInt(proof[i][j])){
c = ph + proof[i];
break;
}
if (parseInt(ph[j]) < parseInt(proof[i][j])){
c = proof[i] + ph;
break;
}
}
ph = crypto.createHash('sha256').update(c).digest("hex");
console.log(ph);
console.log();
}
I have figure it out. The problem was that I was converting the blobs to hex strings and hash them instead of the raw values. For anyone wanting to verify data in node, here is the bare solution:
ledgerInfo.getRevision(params).then(res => {
console.log(res);
const rBlock = makeReader(res.Revision.IonText);
var ph;
rBlock.next();
rBlock.stepIn();
rBlock.next();
while (rBlock.next() != null) {
if (rBlock.fieldName() == 'hash') {
ph = rBlock.byteValue()
}
}
var proof = [];
const rProof = makeReader(res.Proof.IonText);
rProof.next();
rProof.stepIn();
while (rProof.next() != null) {
proof.push(rProof.byteValue());
}
for (var i = 0; i < proof.length; i++) {
var c;
if (hashComparator(ph, proof[i]) < 0) {
c = concatTypedArrays(ph, proof[i]);
}
else {
c = concatTypedArrays(proof[i], ph);
}
var buff = crypto.createHash('sha256').update(c).digest("hex");
ph = Uint8Array.from(Buffer.from(buff, 'hex'));
}
console.log(Buffer.from(ph).toString('base64'));
}).catch(err => {
console.log(err, err.stack)
});
function concatTypedArrays(a, b) {
var c = new (a.constructor)(a.length + b.length);
c.set(a, 0);
c.set(b, a.length);
return c;
}
function hashComparator(h1, h2) {
for (var i = h1.length - 1; i >= 0; i--) {
var diff = (h1[i]<<24>>24) - (h2[i]<<24>>24);
if (diff != 0)
return diff;
}
return 0;
}

Instagram Auto-Like JavaScript BOT

This code brings back an error of
Uncaught TypeError: Cannot read property 'innerHTML' of null
at doLike (<anonymous>:20:21)
at <anonymous>:35:1
doLike # VM1269:20
(anonymous) # VM1269:35
It has worked in the past, I got it from this website : https://blog.joeldare.com/simple-instagram-like-bot/
function getHeartElement() {
var knownHeartElementNames = ["coreSpriteHeartOpen", "coreSpriteLikeHeartOpen"];
var i = 0;
// Loop through the known heart elements until one works
for (i = 0; i < knownHeartElementNames.length; i++) {
var heartElement = document.querySelector("." + knownHeartElementNames[i]);
if (heartElement != undefined) {
break;
}
}
return heartElement;
}
function doLike() {
var likeMax = 100;
var likeElement = getHeartElement();
var nextElement = document.querySelector(".coreSpriteRightPaginationArrow");
likeCount++;
var nextTime = Math.random() * (14000 - 4000) + 4000;
if (likeElement.innerHTML.match("Unlike") == null) {
likeElement.click();
console.log(likeCount + " - liked");
} else {
console.log(likeCount + " - skipped");
}
setTimeout(function() {nextElement.click();}, 1000);
if (likeCount < likeMax) {
setTimeout(doLike, nextTime);
} else {
console.log("Nice! Time for a break.");
}
}
var likeCount = 0;
doLike();
You may want to use a tool such a Keygram - https://www.thekeygram.com
It works really well for me to gain followers

Text version compare in FCKEditor

Am using Fck editor to write content. Am storing the text as versions in db. I want to highlight those changes in versions when loading the text in FCK Editor.
How to compare the text....
How to show any text that has been deleted in strike through mode.
Please help me/...
Try google's diff-patch algorithm http://code.google.com/p/google-diff-match-patch/
Take both previous and current version of the text and store it into two parameters. Pass the two parameters to the following function.
function diffString(o, n) {
o = o.replace(/<[^<|>]+?>| /gi, '');
n = n.replace(/<[^<|>]+?>| /gi, '');
var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/));
var str = "";
var oSpace = o.match(/\s+/g);
if (oSpace == null) {
oSpace = ["\n"];
} else {
oSpace.push("\n");
}
var nSpace = n.match(/\s+/g);
if (nSpace == null) {
nSpace = ["\n"];
} else {
nSpace.push("\n");
}
if (out.n.length == 0) {
for (var i = 0; i < out.o.length; i++) {
str += '<span style="background-color:#F00;"><del>' + escape(out.o[i]) + oSpace[i] + "</del></span>";
}
} else {
if (out.n[0].text == null) {
for (n = 0; n < out.o.length && out.o[n].text == null; n++) {
str += '<span style="background-color:#F00;"><del>' + escape(out.o[n]) + oSpace[n] + "</del></span>";
}
}
for (var i = 0; i < out.n.length; i++) {
if (out.n[i].text == null) {
str += '<span style="background-color:#0C0;"><ins>' + escape(out.n[i]) + nSpace[i] + "</ins></span>";
} else {
var pre = "";
for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) {
pre += '<span style="background-color:#F00;"><del>' + escape(out.o[n]) + oSpace[n] + "</del></span>";
}
str += " " + out.n[i].text + nSpace[i] + pre;
}
}
}
return str;
}
this returns an html in which new text is marked green and deleted text as red + striked out.

Resources