Discord.js Promise { <pending> } endb - discord.js

So when i run my code in discord and put the prefix then i get Promise { pending } and not the value that i set to the endb.
My Code:
const Endb = require('endb');
const endb = new Endb({
store: new Map(),
namespace: 'Cache',
});
endb.set(msg.guild.id,"Random")
console.log(endb.get(msg.guild.id))
Can someone help me?

endb.get(msg.guild.id) returns a Promise that you will have to await.
endb.get(msg.guild.id).then((data) => {
console.log(data);
});
I also recommend you use something else other than endb since it is no longer maintained.

Related

React 17 useMemo create a losted instance of object

[EDIT]
Thanks to #dbuchet for his anwser. The problem comes from the fact that in StrictMode in dev mode only, everythings is running twice.
[PROBLEM]
I just got a weird beavour in React.
My context :
I want to create an EventSource for work with Mercure. So i created a hook and this hook store my EventSource with a useMemo. Until here everything's is fine. But after some tests, eachtime i call my hook, two connections are created not only one.
The problem is that i am not able to close the first connection. Only the second. This cause memory leak and undesired persistent connections.
My useMemo for the EventSource :
const eventSource = useMemo(() => {
if (topics.length === 0 || !hubUrl || !baseUrl) {
return null;
}
let url = new URL(hubUrl);
topics.forEach(topic => {
url.searchParams.append('topic', (baseUrl ? baseUrl : '') + topic);
});
return new EventSource(url, {
withCredentials: withCredentials
});
}, [baseUrl, hubUrl, withCredentials, topicsHash]);
After some investigations, i can see that if i add some Math.random(), logs and a simple setInterval, i am able to see that two different objects are created :
const eventSource = useMemo(() => {
if (topics.length === 0 || !hubUrl || !baseUrl) {
return null;
}
let url = new URL(hubUrl);
topics.forEach(topic => {
url.searchParams.append('topic', (baseUrl ? baseUrl : '') + topic);
});
console.log('opening... ' + temp)
let connectionInterval = null;
connectionInterval = setInterval(() => {
console.log('------------- setInterval ---------------')
onsole.log(topics, eventSource, temp);
clearInterval(connectionInterval);
});
let test = { test: temp, eventSource: new EventSource(url, {
withCredentials: withCredentials
})}
return test;
}, [baseUrl, hubUrl, withCredentials, topicsHash]);
The result in the logger is :
So we can see that my useMemo seems to be called only once (due to the fact that 'opening...' log is visible only once). But the random is different of the final object that i have at the end.
Moreover, setInterval is executed twice with both randoms visible.
Maybe something in my project cause this, so i created a simple peice of React and try the code below and same beavour :
const temp = useMemo(() => {
let test = Math.random();
let inter = setInterval(() => {
console.log('setInterval');
console.log(test);
clearInterval(inter);
});
console.log(test);
}, ['for block reloading'])
Result of the console :
Anyone got the same problem ?
Is there a way to avoid this, maybe i made a mistake somewhere or i misunderstood something with useMemo ?
Thanks !

How to wait for getDownloadURL to finish in my mapping function before updating my object array in react state?

getImages() {
const entries_copy = this.state.entries;
entries_copy.map(entry => {
storage.refFromURL(entry.sign_in_photo).getDownloadURL()
.then((url) => {
entry["inPhotoURL"] = url;
storage.refFromURL(entry.sign_out_photo).getDownloadURL()
.then((url) => {
entry["outPhotoURL"] = url;
});
}).catch((error) => {
// Handle any errors
});
});
this.setState({entries: entries_copy});
}
I'm trying to retrieve the download url for images and store them in my entry object inside my entries object array but the problem I'm facing right now is that the setState is called before the urls are retrieved and I have no idea how to wait for it to complete before setting the state. I have searched for similar problems but most of them are solved by executing it inside then() but for mine, I can't execute it inside then() because I have to wait for all the entries to be updated. I have only recently started using React for this project so I'm sorry if the answer is obvious.
This is because the code in asynchronous.
You should call setState inside the .then() function.
I would recommend you to read about Promises in Javascript. They are an important aspect of the language to master.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
In addition to the answer of #TomSlutsky, note that you need to correctly chain your promises and you should not forget to "always return results, otherwise callbacks won't catch the result of a previous promise".
So you need to do as follows:
storage.refFromURL(entry.sign_in_photo).getDownloadURL()
.then((url) => {
entry["inPhotoURL"] = url;
return storage.refFromURL(entry.sign_out_photo).getDownloadURL()
})
.then((url) => {
entry["outPhotoURL"] = url;
this.setState(...);
})
.catch((error) => {
// Handle any errors
});
Note also how the catch() method is called at the end of the chain, see the doc for more details (and possible other options).

Node.js beginner struggling with arrays, promises and Async

A node.js (and coding in general) beginner here, struggling with the async nature of node. I'm trying to write some code that will look up the members of certain AD groups and add the member names to an array, as per the "getMembers" function below. I'm only interested in computer objects, which is why I only have ad.find returning "other" objects.
Once that is complete, I want the "processAssets" function to do something with the array - for the purpose of testing, just ouptutting to the console.log. The problem is that "processAssets" is running before "getMembers" has populated the array. What am I doing wrong? I realise the answer may begin with "several things"...!
const ActiveDirectory = require('activedirectory');
var ad = new ActiveDirectory(config);
var query = 'memberOf=cn=';
var cNames = [
'group1',
'group2',
'group3'
];
var baseOu = ',ou=Groups,dc=example,dc=com';
function run(cNames) {
Promise.all(cNames.map(cName => getMembers(cName))).then(processAssets())
}
async function getMembers(cName) {
await ad.find(query + cName + baseOu, async function(err, results) {
if ((err) || (! results)) {return;}
await _.each(results.other, function(other) {
assetArray.push(other.cn);
});
});
}
function processAssets() {
console.log("Contents of assetArray (" + assetArray.length + " assets):");
assetArray.forEach(function(item) {
console.log(item);
});
}
thanks in advance.
You have some things mixed up.
The main problem causing your immediate issue is this line:
Promise.all(cNames.map(cName => getMembers(cName))).then(processAssets())
You need to pass a function to then() which will be called when the promise resolves. You are not doing that, you are passing it the result of calling processAssets(), which has the effect of calling processAssets() immediately. Typically you would us something like:
Promise.all(cNames.map(cName => getMembers(cName))).then(() => processAssets())
/* ^^ pass a function */
Additionally you are await things for no purpose. There's no reason to await here:
await ad.find(query + cName + baseOu, async function(err, results) {
ad.find doesn't return a promise. In general functions that take callbacks don't return promises (maybe there are some exceptions, but I can't think of any). If you want to have a promise to use in run()'s Promise.all you need to wrap the find function in a promise and return it. Something like:
function getMembers(cName) {
return new Promise((resolve, reject) => {
ad.find(query + cName + baseOu, function(err, results) {
if (err) return reject(err)
// I'm making some assumptions about results. But hopefully this gives
// a good enough idea
let data = results.other.map(other => other.cn)
resolve(data)
});
});
}
Now getMembers returns a promise that resolves to the result of ad.find and you can use it in `Promise.all.

ionic Async-await not working

my code is:
async getDetails(){
for(var i=0;i<this.results.length;i++){
// this.booking.length=0;
// this.hbl.length=0;
var hblList=[];
var bookingList=[];
await this.api.get("track/dtl",
{
loadPortId: this.results[i].loadPortId,
dischargeId:this.results[i].dischargeId,
scheduleId: this.results[i].scheduleId
})
.subscribe(res1 => {
//let resp1 = res1;
this.details= res1;
bookingList.length=0;
hblList.length=0;
for(var j=0;j<this.details.length;j++){
if(this.details[j].bookNo!== undefined){
bookingList.push(this.details[j]);
}else if(this.details[j].hblNo!== undefined){
hblList.push(this.details[j]);
}
}
// this.results[i]["hbl"]=this.hbl;
// this.results[i]["booking"]=this.booking;
console.log("this.hbl inside subscribe::::::::::::"+hblList);
console.log("this.booking inside subscribe::::::::::::"+bookingList);
console.log("this.results[i] after::::::::::::"+this.results[i]);
});
this.results[i]["hbl"]=hblList;
this.results[i]["booking"]=bookingList;
console.log("this.hbl after::::::::::::"+hblList);
console.log("this.booking after::::::::::::"+bookingList);
console.log("this.results[i] after::::::::::::"+this.results[i]);
this.getCurrent(this.results[i].queries[0]);
}
}
I want to make async call for each for loop item. could anyone please help me to use async-await to make sure the first and every async call is completed prior to the next call.
Thanks in advance
As you are subscribing in the Observable you're not using the async/await approach. Async/await works only with Promises, so, you need to transform your observable to promise first.
I don't know how your this.api works, but, maybe, you should have a toPromise() function. Using await you won't need to subscribe or to use ".then()" promise function.
I have no means of trying your code or trying mine, but here, take a look at this one that should work in theory.
The main point is: you have to decide whether to use Observables or to use Promises. Unfortunately the Angular team decided to return Observables in their http module. Observables do not work with async await, but there is a simple conversion: Observable.prototype.toPromise(). Use that, and get rid of .subscribe.
async getDetails(){
for(var i=0;i<this.results.length;i++){
// this.booking.length=0;
// this.hbl.length=0;
var hblList=[];
var bookingList=[];
var res1 = await this.api.get("track/dtl", {
loadPortId: this.results[i].loadPortId,
dischargeId:this.results[i].dischargeId,
scheduleId: this.results[i].scheduleId
}).toPromise();
this.details= res1;
bookingList.length=0;
hblList.length=0;
for(var j=0;j<this.details.length;j++){
if(this.details[j].bookNo!== undefined){
bookingList.push(this.details[j]);
} else if(this.details[j].hblNo!== undefined){
hblList.push(this.details[j]);
}
}
this.results[i]["hbl"] = hblList;
this.results[i]["booking"] = bookingList;
console.log("this.hbl after::::::::::::"+hblList);
console.log("this.booking after::::::::::::"+bookingList);
console.log("this.results[i] after::::::::::::"+this.results[i]);
this.getCurrent(this.results[i].queries[0]);
}
}

React findOne returning undefined on Client

I'm having problems using findOne because it always returns undefined.
This code:
Routine.js
Meteor.methods({
.... // Some lines missing
'routines.getRoutine'(routineId) {
check(routineId, String);
return Routines.findOne(routineId);
},
});
Note: If I do a console.log of Routines.findOne(routineId) it correctly shows the element that i'm looking for.
App.jsx
handleSubmit(event) {
event.preventDefault();
const comment = ReactDOM.findDOMNode(this.refs.comment).value.trim();
Meteor.call('routines.addComment', this.state.routine._id, comment);
let a = Meteor.call('routines.getRoutine', this.state.routine._id);
ReactDOM.findDOMNode(this.refs.comment).value = '';
this.setState({
routine: a,
});
}
In my Appjs doesn't matter how I try 'a' is always undefined, what am I doing wrong?
Thanks for the help in advance!
I'm pretty sure your problem is that Meteor calls on the client are async and so the method you're calling hasn't completed by the time you're querying the same data.
Try putting the rest of the code in the callback like so:
handleSubmit(event) {
event.preventDefault();
const comment = ReactDOM.findDOMNode(this.refs.comment).value.trim();
Meteor.call('routines.addComment', this.state.routine._id, comment, function() {
let a = Meteor.call('routines.getRoutine', this.state.routine._id);
ReactDOM.findDOMNode(this.refs.comment).value = '';
this.setState({
routine: a,
});
});
}

Resources