How to get make asyc get with CognitoIdentityCredentials - javascript

After declaring the cred object with new AWS.CognitoIdentityCredentials I go ahead and use .get method to get the credentials and store them in IdentityId variable. When I run this function, the IdentityId variable is show to be undefined. It seems the
console.log("...IdentityId:", IdentityId); is evaluated before the credenitals are queried.
Is there a way I could use await to get the the credentials first and then move to the console.log command ?
async function GetCredentials(email, password, callback) {
let response = await signIn(email, password);
console.log("...response:", response);
let idToken = response.response.token.idToken;
let logins = {};
logins[
"cognito-idp." + AWS_REGION + ".amazonaws.com/" + AWS_COGNITO_USER_POOL_ID
] = idToken;
console.log("...logins:", logins);
let creds = new AWS.CognitoIdentityCredentials({
IdentityPoolId: AWS_COGNITO_IDENTITY_POOL_ID,
Logins: logins
});
console.log("...creds:", creds);
let IdentityId;
creds.get(function(err) {
console.log("--------------------------")
console.log('creds.data:', creds.data);
IdentityId = creds.data.IdentityId;
console.log("--------------------------")
});
}

You could try
const promise = new Promise((resolve) => {
creds.get(function(err) {
console.log("--------------------------")
console.log('creds.data:', creds.data);
const IdentityId = creds.data.IdentityId;
resolve(IdentityId)
console.log("--------------------------")
});
})
const returned = await promise
But I'm not sure where exactly you're using IdentityId because your statement
It seems the console.log("...IdentityId:", IdentityId); is evaluated before the credenitals are queried.
doesn't exist in your code

Related

Promise returns undefined nodejs

i am back with a same issue for my promise returning undefined please help.
Here, i am using ipfs to save data with savedata() which takes in a json string,a document name and a secret phrase.
i am not quit sure why promise is returning undefined i have checked everything
here is the new code
index.js
exports.savedata = async function savedata(jsondata,Docname,secretuuid){
const docname = Docname
let ipfss = await main();
let datavar = await ipfss.add(jsondata);
//check if input file exists or not?
const fpath = __dirname + "\\"+ "input.json"
if (fs.existsSync(fpath)) {
}
else{
const defobj = {defaultID:"defaultID"}
fs.writeFile("input.json",JSON.stringify(defobj),function(err){
// console.log('saved!')
})
}
//create an object and put an array with defaultid:defaultid to it
//take that object and keep concatenating the new arrays[new documents]
fs.readFile("input.json","utf-8",function(err,data){
if(err){
console.log(err)
}
const rembrk1 = data.replaceAll("{","")
const rembrk2 = rembrk1.replaceAll("}","")
const newstring = JSON.stringify({[docname]: datavar.path})
const URK = uuidv4() + "rkbyavds"
const CAT = CryptoJS.AES.encrypt(String(datavar.path),secretuuid);
var ENCAT = CAT.toString()
const fstring = "{" + rembrk2 + "," + docname + ":" + CAT + "}"
fs.writeFile("input.json", JSON.stringify(fstring),function(err){
if(err){
console.log(err)
}
})
return new Promise((resolve,reject) => {
// console.log('saved')
const retobj = {CAT:ENCAT,URK:URK}
resolve(retobj)
});
})
}
test.js
obj = JSON.stringify({user:"MqwMedz2edemusaaa",age:1291})
const op = savedata(obj,"doc1","verysecretuuid")
op.then(x=>{
console.log(x)
})
Well, the RegisterUser function executes the actions and retrieves the data. What it doesn't do is return any value. This means it'll return a Promise by default, but this Promise won't have any value to resolve.
Depending on which object you want to have returned, you need to return it or create and return a new Promise from which you can call the resolve-function.
You can read more about it here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Discord JS bot how to make a recursive async function fetching from API

I am trying to make a discord bot. I want it to fetch an API every X seconds and check for new topics created.
The API JSON contains just one object, the latest post on the site. I wanted the bot to fetch every X seconds and if the latest post found has a bigger uid to send a message in a channel. If not do nothing. The uid is a number.
Tried to use the setInterval function but could not get it to work as it gave out errors that await needs to be in a top async function.
I also hardcoded the latest post uid "latest_post" and the way I saw it working is if post_id from API is higher that the hardcoded one then hardcoded one receives the value of the new one. However latest_post's value remains unchanged as the function is executed again and lates_post is hardcoded every time. Tried to declare it outside the function but came out as undefined.
This is my current almost working code
client.on('messageCreate', async (message) => {
if (!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (command === 'new') {
var latest_post = 12345; // hardcoded latest post uid
try {
const response = await fetch('API HERE').then(r => r.text());
const body = JSON.parse(response);
const obj = body.data;
const objId = obj[0].post_id;
const objAuthor = obj[0].author;
const objTitle = obj[0].title;
if (objTopic > latest_post) {
client.channels.cache.get("CHANNEL ID").send(`Found a new post by ${objAuthor}`);
var latest_post = objId; // if it fetches a post with a higher uid then latest_post receives the value of that higher uid
} else {
var d = new Date();
var n = d.toLocaleTimeString();
console.log(`No new posts yet at ${n}`); //logs "No new posts yet at 1:30 PM"
}
} catch (error) {
message.channel.send('Oops, there was an error fetching the API');
console.log(error);
}
}
});
Can anyone guide me how to transform this in a recursive function that runs automatically every X seconds.
Thanks !
After some iterations managed to make it work the way I wanted. Will leave the code below, hope it helps!
let refreshint = 10 * 1000; //10 seconds
var API = "API_HERE";
client.on('ready', async (message) => {
console.log('Bot is connected...');
var latest_post = 12345 // hardcoded latest post uid
setInterval(async function(){
try {
const response = await fetch('API').then(r => r.text());
const body = JSON.parse(response);
const obj = body.data;
const objId = obj[0].post_id;
const objAuthor = obj[0].author;
const objTitle = obj[0].title;
if (objTopic > latest_post)
client.channels.cache.get("CHANNEL ID").send(`Found a new post by ${objAuthor}`);
console.log(`Found a new post by ${objAuthor}`);
function change_value(latest_post){
return latest_post;
}
latest_post = change_value(topicId);
} else {
var d = new Date();
var n = d.toLocaleTimeString();
console.log(`No new thread yet at ${n}`);
}
} catch (error) {
message.channels.cache.get('channel ID here').send('Oops, there was an error fetching the API');
console.log(error);
}
}, refreshint) });

RequestError: Requests can only be made in the LoggedIn state, not the SentClientRequest state NODEJS MSSQL(7.11.2)

RequestError: Requests can only be made in the LoggedIn state, not the SentClientRequest state
I am using NodeJS MSSQL(7.11.2)
I get this error when using transaction and requests but not when using just the query.
const result = await sql.query("select * from TagDefinition"); //this works
I read the documentation but I can't seem to find a way to address that.
Do you have an idea on how I could address that?
I stripped the code to a minimum and the exception seems to get fired off at
request.query("select * from TagDefinition"); //this sends the exception
await sql.connect(this.sqlConfig);
const result = await sql.query("select * from TagDefinition");
console.log(result);
const transact = new sql.Transaction();
await transact.begin(e=>{
console.log(e)
const request = new sql.Request(transact);
request.query("select * from TagDefinition");
transact.commit(e=>{console.log(e)});
});
Thank you for your suggestion https://stackoverflow.com/users/390122
const t = new sql.Transaction()
t.begin(e =>{
const r = new sql.Request(t)
r.query("INSERT INTO[Permission] ([Name]) VALUES('test')", e=>{
t.commit(e=>{
console.log("it worked")
})
})
})
this worked.
For future reference, I also tried this
const transact = new sql.Transaction();
await transact.begin()
const request = new sql.Request()
request.query("INSERT INTO[Permission] ([Name]) VALUES('testt')");
transact.commit();
and this
//sql.connect(this.sqlConfig);
const pool = new sql.ConnectionPool(sqlConfig);
const connectionPool = await pool.connect()
const t = connectionPool.transaction()
await t.begin();
const r = t.request();
await r.query("INSERT INTO[Permission] ([Name]) VALUES('testt')");
await t.commit();
console.log("worked ")
And they both work too.

Await isn't waiting?

Hi I've got two functions. They're called inside another function. And I need the second function execute after the first is done.
I'm sorry this is probably a very simple question, but I'm still trying to wrap my head around promises and async/await in js. Can anyone help me figure out why this isn't working.
async function addDetails(){
const sub = await getSession();
// now wait for firstFunction to finish...
addProfileDetails(sub);
};
I have debug/logging statements in both. So I know that addProfileDetails is being executed before the variable sub is defined.
I'm using react native and node.js
EDIT:
export function getSession() {
console.log("checking user ...............................................")
Auth.currentSession().then(res=>{
console.log("retrieving token");
let accessToken = res.getAccessToken()
let payload = accessToken.payload;
console.log(`sub: ${payload.sub}`)
return payload.sub
})
};
This is my getSession() function. It also needs to be async?
You must return a promise from the function that you want to await
export function getSession() {
console.log("checking user ...............................................")
return Auth.currentSession().then(res=>{
console.log("retrieving token");
let accessToken = res.getAccessToken()
let payload = accessToken.payload;
console.log(`sub: ${payload.sub}`)
return payload.sub
})
};
Try this in your getSession
export function getSession() {
return new Promise((resolve, reject) => {
console.log("checking user ...............................................")
Auth.currentSession().then(res=>{
console.log("retrieving token");
let accessToken = res.getAccessToken()
let payload = accessToken.payload;
console.log(`sub: ${payload.sub}`)
resolve(payload.sub)
})
};

NodeJS Wait till a function has completed

I have an application where i have a Client class, that needs to be executed with different configurations for each user when i receive a message on discord(It's a chat application having its own API calls for checking for new messages etc). I have initialized the obj constructor whenever i receive a new message with new configurations for that user, but the problem is when i receive multiple messages at the same time, only the latest user's configurations are used for all the client objects created. Attaching sample code from the application:
Wait for message code:
const app = require("./Client")
const app2 = require("./MyObject")
bot.on('message', async (message) => {
let msg = message.content.toUpperCase(), pg;
let client = await new app2.MyObject();
//set all such configurations
config.a = "valuea";
// initialize my
pg = await new app.Client(config, client);
let result = await pg.Main(bot, message, params).then((result) => {
// Do stuff with result here
});
});
Client class:
class Client {
constructor(config, client) {
this.config = config;
this.client = client;
}
async Main(bot, message, params) {
let result = {};
this.client.setProperty1("prop");
await this.client.doSOmething();
result = await this.doSOmethingMore(message);
this.client.doCleanUp();
return result;
}
}
I had also tried initializing the obj constructor in the Client class, but even that fails for some reason.
Any suggestions how Can i correct my code?
You don't need to use .then and await at the same time.
bot.on('message', async (message) => {
let msg = message.content.toUpperCase();
let client = await new MyObject();
//set all such configurations
config.a = "valuea";
// initialize my
pg = new app.Client(config, client);
let result = await pg.Main(bot, message, params);
// Do stuff with result here
console.log(result);
});
(You don't need to use await at constructor call because it is not an async method)
note: async-await will work on higher version of node than 7.6
If you want to use .then:
bot.on('message', (message) => {
let msg = message.content.toUpperCase();
new MyObject().then(client => {
//set all such configurations
config.a = "valuea";
// initialize my
pg = new app.Client(config, client);
pg.Main(bot, message, params).then(result => {
// Do stuff with result here
console.log(result);
});
});
});
It's difficult to be certain, since you don't include the MyObject code, but generally it's a bad practice to return a promise from a constructor.
Further, if you don't do it right, then whatever that promise resolves to might not in fact be the Client that your calling code expects.

Categories

Resources