How to run this function on an interval? - javascript

I am trying to run everything within the checkUser() function but its not running on the interval specified. Maybe there is a better way to do this? I am just trying to check the address every few minutes. The line const accounts = await ethereum.request({ method: 'eth_accounts' }); does get the address and works fine if I just run it once. Just need to try do it on an interval though. Full code below:
function checkUser()
{
window.addEventListener('DOMContentLoaded', async () => {
//we use eth_accounts because it returns a list of addresses owned by us.
const accounts = await ethereum.request({ method: 'eth_accounts' });
//We take the first address in the array of addresses and display it
// getAccountsResult.innerHTML = accounts[0] || 'not able to get accounts';
console.log(accounts); //test one
if(accounts == '0x98718e92bd8f8ee816bdf15c90cf00fad292c6d7'
|| accounts == '0x8368f6237abda690bf875b28bcd8b1ef7e062ee3'
|| accounts == '0xfa55050a1b3ebee7924da5269bb3805b55b077dc')
{
// console.log("you are going in!");
// window.location.href = "members_home.html";
}
else
{
console.log(accounts); //test one
window.location.href = "normal_home.html";
}
});
}
setInterval(checkUser, 50);

This function adds an eventListener on DOMContentLoaded. So when you run this function at an interval you create a new eventlistener every 50ms. If you want to run the function inside eventListener at the specified interval you can put it in a seperate function.
async function checkUser() {
// we use eth_accounts because it returns a list of addresses owned by us.
const accounts = await ethereum.request({ method: 'eth_accounts' });
// We take the first address in the array of addresses and display it
// getAccountsResult.innerHTML = accounts[0] || 'not able to get accounts';
console.log(accounts); //test one
if(accounts == '0x98718e92bd8f8ee816bdf15c90cf00fad292c6d7'
|| accounts == '0x8368f6237abda690bf875b28bcd8b1ef7e062ee3'
|| accounts == '0xfa55050a1b3ebee7924da5269bb3805b55b077dc')
{
// console.log("you are going in!");
// window.location.href = "members_home.html";
}
else
{
console.log(accounts); //test one
window.location.href = "normal_home.html";
}
}
window.addEventListener('DOMContentLoaded', checkUser);
setInterval(checkUser, 50);
This way the function gets executed when the dom content is loaded and every 50ms.

Why are DOMContentLoaded and setInterval inside your checkUser function ?
Your instructions order is all wrong.
Reading your code, I think you don't even want to use setInterval...
I guess what you want to do is :
wait for DOMContentLoaded to define checkUser
checkUser to do the ethereum.request
window.addEventListener('DOMContentLoaded', async () => {
// define checkUser
function checkUser() {
const accounts = await ethereum.request({ method: 'eth_accounts' });
//We take the first address in the array of addresses and display it
// getAccountsResult.innerHTML = accounts[0] || 'not able to get accounts';
console.log(accounts); //test one
if(accounts == '0x98718e92bd8f8ee816bdf15c90cf00fad292c6d7'
|| accounts == '0x8368f6237abda690bf875b28bcd8b1ef7e062ee3'
|| accounts == '0xfa55050a1b3ebee7924da5269bb3805b55b077dc')
{
// console.log("you are going in!");
// window.location.href = "members_home.html";
}
else
{
console.log(accounts); //test one
window.location.href = "normal_home.html";
}
}
// run checkUser
checkUser();
}

Related

Chrome extension: chrome local storage is not set instantly

I am having strange issues with Chrome Local storage setting and retrieval.
In background.js I am setting it when a certain URL's HTML is fetched once the page loading is completed and then in content.js I am fetching values from local storage. At times it is stored and fetched instantly while other times results.html is undefined. And if I use chrome.storage.local.clear() it makes it more worst, make you to refresh the page 2-3 times at least. Below is my code:
background.js
chrome.runtime.onMessage.addListener(
async function(request, sender, sendResponse) {
// Reset storage
// chrome.storage.local.clear() // it is lagging refreshing values
sendResponse("bar")
// Check whether it is correct URL
var url = 'http://localhost:8000/get.php?url='+request
console.log('URL for AJAX =',url)
var result = await sendReq(url)
var json_result = JSON.parse(result)
var status = json_result['status']
var rules = []
console.log('Status = '+status)
if(status == 'ok') {
rules = json_result['msg']['rules']
chrome.storage.local.set({'rules': rules}, function() {});
url = 'http://localhost:8000/read.php?url='+request
result = await sendReq(url)
// console.log(result)
chrome.storage.local.set({'html': result}, function() {}); // this goes undefined if the URL of visiting page is changed.
} else {
// To check on content script
chrome.storage.local.set({'html': '__FAIL__'}, function() {});
}
}
);
content.js (Using JQuery)
$(function() {
// console.clear()
console.log('The Agile Super Cluster extension cleared all previous output')
chrome.storage.local.get(['html','rules'], function(result) {
// Do not perform things below if it is not a relevant Super Cluster URL
if(result.html == '__FAIL__' || typeof (result.html) == 'undefined') {
return
}
.....
// Out of onReady() block
chrome.runtime.sendMessage(
url,
function (response) {
console.log('Sending Response')
console.log(response);
}
);
The solution is to use messaging correctly so you can wait on the result reliably.
remove chrome.storage, it's not necessary for this task;
remove async from onMessage listener (why?) and use a separate async function to get info;
return the result via sendResponse + return true.
content.js:
chrome.runtime.sendMessage(url, res => {
console.log(res);
if (res.html) {
// use `res.html` here
}
});
background.js:
const API_GET = 'http://localhost:8000/get.php?url=';
const API_READ = 'http://localhost:8000/read.php?url=';
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
getInfo(request).then(sendResponse);
return true; // keep the channel open for asynchronous sendResponse
});
async function getInfo(url) {
const res = JSON.parse(await sendReq(`${API_GET}${url}`));
return res.status === 'ok' ? {
rules: res.msg.rules,
html: await sendReq(`${API_READ}${url}`),
} : {};
}

how can i access variables values from a netlify function to call API?

hope someone can help me.
I'm trying to deploy a web app on netlify, but i don't know how to call the API the right way, providing the right value.
this is my netlify function file:
const fetch = require('node-fetch');
exports.handler = async event => {
const API_KEY = process.env.API_KEY;
const response = await fetch(`https://api.waqi.info/feed/${process.env.CITY}/?token=${API_KEY}`);
const data = await response.json();
const pass = (body) => {
return {
statusCode: 200,
body: JSON.stringify(body)
}
};
return pass(data);
}
My problem is about providing the right city value to the API call.
i've also tried to make city an env var on netlify, but even if i change its value, the file lambda.js provides me always the same value probably because it runs just one time at the start.
Here's the code in index.js:
let CITY = process.env.CITY;
async function getCityPollution(city) {
let response = await fetch("/.netlify/functions/lambda");
let result = await response.json();
if(response.status == 200 && result.status == 'ok') {
await dataHandler(result);
console.log(result);
} else if (result.status == 'error'){
console.log(`${result.status}: ${result.data}`);
setTimeout(() => {
dataParagraph.innerHTML = `Unfortunately we have no datas for ${city} station (incredible but true),
insert coords to check datas from the nearest station or try with another city.
Go check https://waqi.info/ to see our coverage`;
$("html, body").animate({ scrollTop: document.body.scrollHeight }, "slow");
}
, 50);
} else {
console.log(response.status);
}
}
// getting city input and call output function
let getCity = document.querySelector('#getCity');
getCity.onclick = async () => {
CITY = cityInput.value;
if (!CITY) {
emptyFields(cityInput);
} else {
await getCityPollution(CITY);
coordInput[0].value = '';
coordInput[1].value = '';
console.log(CITY) //it works, the value changes
}
}
Obviously this is the try with the netlify env var. This way i get always the same value.
There's a way to pass the right value of CITY everytime i need it? Even without using env variables.
Thank you in advance

clearTimeOut function for not working while using with discord.js

I am trying to make a bot that deletes a channel ('general') after 10 min after calling execcmd() function but if the msg is sent by someone having 'idofsomeuser' then it should cancel the previous timeout and start the timer again. But it's not working.
function execcmd(msg) {
let ID = msg.author.id
let chan = msg.guild.channels.cache.find(
(channel) => channel.name === 'general'
);
x = 'idofsomeuser'
if (ID == x) {
clearTimeout(x);
ID = setTimeout(() => {
chan.delete();
}, 600000); //10min
} else {
x = setTimeout(() => {
chan.delete();
}, 600000);
}
}
execcmd(msg); //msg is received by client and passed here
Create a closure function in which you store the timeout variable. Doing this enables you to store the timeout safely without having to create a global variable to store it in.
Inside the callback function first check if the id of the author matches. If it does, clear the timeout and set it to null. Then check if the timeout is equal to null and start the timer.
So now the timer will start when the function is called for the first time, and is restarted everytime the user with the id you're looking for is found.
function createClearChannel(channelName, authorId) {
let timeout = null;
const timeoutDuration = 1000 * 60 * 10;
return function (msg) {
const isAuthor = authorId === msg.author.id;
const channel = msg.guild.channels.cache.find(
channel => channel.name === channelName
);
if (isAuthor) {
clearTimeout(timeout);
timeout = null;
}
if (timeout === null) {
timeout = setTimeout(channel.delete, timoutDuration);
}
};
}
To set this up, first call the createClearChannel function and pass the arguments below. Store the result in execcmd and call that function when a message enters.
(You could always omit these parameters and simply hardcode the channel name and id of the user, but by doing this you make the function more flexible so it can be used for other cases as well.)
Important: The createClearChannel should only be called ONCE. So don't create a new execcmd when receives each message, but use the same one everytime.
const execcmd = createClearChannel('general', 'idofsomeuser');
execcmd(msg);

Get and check a value from JSON read in NodeJS

I'm trying to check if a user exists (registered on a json file).
Unfortunately I don't find a valid solution in all Stack Overflow that gives me a simple "true" in a callback.
The version closest to a solution
Experiment V1 :
let userExist;
function check(){
console.log("CHECK!");
return userExist = true;
}
// check(); if this, return true... obvious.
//// check if user exist
server.readFileSync(filepath, 'utf8', (err, data) =>
{
let json = JSON.parse(data),
userlist = json.allusers;
for (let key in userlist)
{
if ( userlist[key].email == req.body.user_email )
{
console.log("FINDED EQUAL");
check(); // return undefined ???
}
}
});
console.log("userExist value : "+userExist);
differently formulated the debugs also appear, but "true" never returns.
note: yes, JSON is read correctly. If everything works inside the readfile, you immediately notice the same emails.
output: "undefined"
Log: total bypassed
Experiment V2 :
In this case (with asynchronous reading) it returns all the debugging (but the "true" remains undefined)
The problem with the asynchronous is that I have to wait for it to check to continue with the other functions.
//// check if user exist
server.readFile(filepath, 'utf8', (err, data) =>
{
let json = JSON.parse(data),
userlist = json.allusers;
for (let key in userlist)
{
if (/* json.allusers.hasOwnProperty(key) &&*/ userlist[key].email == req.body.user_email )
{
console.log("FINDED EQUAL");
check();
}
}
});
var userExist;
function check(userExist){
console.log("CHECK!");
return userExist=true;
}
console.log("userExist value : "+userExist+"");
server listening on: 8080
userExist value : undefined
CHECK!
FINDED EQUAL
Experiment V3 :
after the various suggestions I come to a compromise by using the syntax for the async functions.
This allowed to reach an ordered code, but despite this it is not possible to wait for the results and export them out of the same function (this is because node itself is asynchronous! Therefore it has already gone on!)
using a "message" variable to check if it could return an object I did so:
//simple output tester
var message;
// create a promise
let loopusers = new Promise( (resolve)=>{
server.readFile( filepath, 'utf8',
(err, data) => {
let json = JSON.parse(data),
userlist = json.allusers,
findedequal;
console.log("CHECK USERS IN DB...for "+userlist.length+" elements");
// loop all items
for (let key in userlist)
{
console.log("Analyzed key ::: "+key);
if ( userlist[key].email == req.body.user_email )
{
console.log("CHECK : user isn't free");
findedequal=true;
resolve(true); // return the result of promise
}
else if(key >= userlist.length-1 && !findedequal )
{
console.log("CHECK : User is free ;)");
resolve(false); // return the result of promise
}
}
// call the action
createuser();
});
});
// when promise finished --> start action
async function createuser(message)
{
let userExist = await loopusers;
console.log("userExist: "+userExist);
if(userExist)
{
message = { Server: "This user already exists, Try new e-mail..."};
}
else
{
message = { Server: "Registration user -> completed..."};
}
// return values
return message;
};
It is also possible to use the classic syntax via "then". For exemple:
//simple output tester
var message;
// create a promise
let loopusers = new Promise( (resolve)=>{
...
});
loopusers.then( (response)=>{
...
})
Then I realized that it was easy to simplify even more by calling the functions directly from the initial one:
var message;
// create a promise --> check json items
server.readFile( filepath, 'utf8',
(err, data) => {
let json = JSON.parse(data),
userlist = json.allusers,
findedequal;
console.log("CHECK USERS IN DB...for "+userlist.length+" elements");
for (let key in userlist)
{
console.log("Analyzed key ::: "+key);
if ( userlist[key].email == req.body.user_email )
{
console.log("CHECK : user isn't free");
findedequal=true;
createuser(true); // call direct function whit params true
}
else if(key >= userlist.length-1 && !findedequal )
{
console.log("CHECK : User is free ;)");
createuser(false); // call direct function whit params false
}
}
});
// start action
function createuser(userExist)
{
if(userExist)
{
message = { Server: "This user already exists, Try new e-mail..."};
}
else
{
message = { Server: "Registration user -> completed!"};
}
// return values
return message;
};
debugging is taken and written
the message is lost outside the aSync function
Experiment V4 Final! :
Finally, after many attempts the solution! (Yes... But know it's not Async)
If we allocate in a variable the reading becomes synchronous the whole model and we return to the simple one
let message,
file = server.readFileSync(filepath, 'utf8'), // read sync
json = JSON.parse(file), // now parse file
userlist = json.allusers, // get your target container object
userExist,
findedequal;
console.log("CHECK USERS IN DB...for "+userlist.length+" elements");
for (let key in userlist)
{
console.log("Analyzed key ::: "+key);
if ( userlist[key].email == req.body.user_email )
{
console.log("CHECK : finded equal value on key ["+key+"] - user isn't free");
findedequal=true;
userExist = true;
}
else if(key >= userlist.length-1 && !findedequal )
{
console.log("CHECK : User is free ;)");
userExist = false;
}
}
if(userExist)
{
console.log("└ EXIT TO CHECK --> Can't create user, function stop.");
message = { Server: "This user already exists, Try new e-mail..."};
}
else
{
console.log("└ Exit to check --> New user registration ...");
message = { Server: "Registration user -> completed!"};
}
}
return message;
Now:
It's all sync and all log is perfect
all var is checked
all return... return
** Final conclusions: **
Is it possible to retrieve an ASync variable in node?
As far as I understand so far ... no.
Node is async by its nature, therefore recovering information that is not saved and then recovered from a DB is left behind among the things to do, becoming unrecoverable if you use it as in this post.
However ... if the purpose is to make reading a file synchronous, the answer was simpler than expected.
A special thanks to: Barmar; Austin Leehealey; C.Gochev;
The problem is that you are calling console.log("userExist value : "+userExist+"");
too early. At the moment that you call that line, userExist is not defined yet. This is because the server.readFile() function requires a callback and that callback function is executed once it has read the file. However, reading files often take time and so the program keeps going. It executes console.log("userExist value : "+userExist+""); and then goes back to the callback function and defines userExist as true.
If you want more information on what callbacks are look at the link below. Callbacks are a defining feature of Nodejs and understanding them is essential to any Node website.
https://medium.com/better-programming/callbacks-in-node-js-how-why-when-ac293f0403ca
Try something like this.
let userExist;
function check(){
console.log("CHECK!");
return userExist = true;
}
// check(); if this, return true... obvious.
//// check if user exist
server.readFileSync(filepath, 'utf8', (err, data) =>
{
let json = JSON.parse(data),
userlist = json.allusers;
for (let key in userlist)
{
if ( userlist[key].email == req.body.user_email )
{
console.log("FINDED EQUAL");
check(); // return undefined ???
console.log("userExist value : "+userExist);
}
}
});

if else in loop bringing up errors in typescript

I have this function that is supposed to get referral codes from users. User gives a code and the referral code checked if it exists in the database then evaluated if
it does not match the current user, so that one should not refer himself and
it is a match with one of the codes in the database
This code however just does not find a match even if the code given is in the database. If the referral code matches the one of the current user, it works correctly and points that out i.e one cannot refer themselves.
But if the referral code is a match to that of another user which is how a referral system should work, it still says no match.
How can I remove this error
export const getID = functions.https.onCall(async(data, context) => {
const db = admin.firestore();
const usersSnapshot = await db.collection("user").get();
const allUIDs = usersSnapshot.docs.map(doc => doc.data().userID);
const userID = context.auth.uid;
const providedID = "cNx7IuY6rZlR9mYSfb1hY7ROFY2";
//db.collection("user").doc(providedID).collection("referrals").doc(userID);
await check();
function check() {
let result;
allUIDs.forEach(idFromDb => {
if (providedID === idFromDb && (idFromDb === userID)) {
result = "ownmatch";
} else if (providedID === idFromDb && (idFromDb !== userID)) {
result = "match";
} else {
result = "nomatch";
}
});
return result;
}
if (check() === "match") {
return {
message: `Match Found`,
};
} else if (check() === "ownmatch") {
return {
message: `Sorry, you can't use your own invite code`,
};
} else {
return {
message: `No User with that ID`
};
}
});
(This is not an answer, but a simple refactoring.)
This is what your code is currently doing (roughly, I didn't run it):
const resultMsgs = {
nomatch: 'No User With That ID',
ownmatch: 'Sorry, you can\'t use your own invite code',
match: 'Match Found',
}
function check(uids, providedId, userId) {
let result
uids.forEach(idFromDb => {
if (providedId !== idFromDb) {
result = 'nomatch'
return
}
if (userID === idFromDb) {
result = 'ownmatch'
return
}
result = 'match'
})
return result
}
export const getID = functions
.https
.onCall(async (data, context) => {
const userId = context.auth.uid
const providedId = 'cNx7IuY6rZlR9mYSfb1hY7ROFY2'
const db = admin.firestore()
const user = await db.collection('user').get()
const uids = user.docs.map(doc => doc.data().userId)
const checkResult = check(uids, providedId, userId)
return { message: resultMsgs[checkResult] }
})
(I removed the seemingly-spurious db collection operation.)
Your forEach is iterating over all of the uuids, but result will be set to whatever the last comparison was. Perhaps this is correct, but:
If you're looking for any match, this is not what you want.
If you're looking for all matches, this is not what you want.
If you're looking to match the last UUID, it's what you want, but an odd way to go about it.
So:
If you want any matches, use... ahem any form of an any function.
If you want all matches, use any form of an all function.
If you want the first match, then just check the first element.
If you want the complete set of comparisons then you'll need to use map instead of forEach, and handle each result appropriately, whatever that means in your case.
In any event, I'd recommend breaking up your code more cleanly. It'll be much easier to reason about, and fix.

Categories