I am trying to register a user using AWS Cognito. In the below class, the control from theregisterInCognito is not being returned. I have tried adding return after the failure and success conditions too (aren't reject and resolve of the promise the same?). But nothing worked. When I tried debugging, I figured out that the section where I have commented <---- The control is unreachable here. is not being executed. The control itself is in the return function.
export class CompanyCAO {
// change return type from any to meaningful type
private poolData;
private pool_region;
private userPool;
private cognitoUser;
constructor() {
this.poolData = {
UserPoolId: process.env.COGNITO_USER_POOL_ID,
ClientId: process.env.COGNITO_CLIENT_ID
}
this.pool_region = process.env.COGNITO_POOL_REGION;
this.userPool = new AmazonCognitoIdentity.CognitoUserPool(this.poolData);
}
public create(regInfo: Company): Promise < any > {
return new Promise < boolean > (async(resolve, reject) => {
this.registerInCognito(regInfo);
});
}
public registerInCognito(regInfo: Company): Promise < boolean > {
return new Promise < boolean > (async(resolve, reject) => {
let attributes = process.env.COGNITO_AUTH_ATTRIBUTES!.split(",");
let attributeValues = Array < string > ();
let attributesList = Array < any > ();
for (var attribute in attributes) {
for (var attributeName in regInfo) {
if (((typeof regInfo[attributeName]) != 'object') && (attributes[attribute] == attributeName)) {
attributeValues.push(regInfo[attributeName]);
} else if ((typeof regInfo[attributeName]) === 'object') {
for (var subAttributeName in regInfo[attributeName]) {
if (subAttributeName == attributes[attribute]) {
attributeValues.push(regInfo[attributeName][subAttributeName]);
}
}
}
}
}
for (var index in attributes) {
attributesList.push(new AmazonCognitoIdentity.CognitoUserAttribute({
Name: attributes[index],
Value: attributeValues[index]
}));
}
const randomPassword = this.createRandomPassword();
console.log(`Password is ${randomPassword}`);
await this.userPool.signUp(regInfo.Admin.EmailAddress, randomPassword, attributesList, null, (err, result) => {
if (err) {
console.error(err);
reject(err);
} else {
this.cognitoUser = result.user;
}
}).promise().then((value: any) => {
resolve(true);
}).catch(error => {
reject(error);
})
});
// <---- The control is unreachable here.
}
public createRandomPassword() {
let password = '';
const alphaCharacters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
const numberCharacters = '1234567890';
const specialCharacters = '!##$%^&**()?/><}{';
const iterations = 5;
for (let i = 0; i < iterations; i++) {
password += alphaCharacters.charAt(Math.floor(Math.random() * alphaCharacters.length));
password += numberCharacters.charAt(Math.floor(Math.random() * numberCharacters.length));
password += specialCharacters.charAt(Math.floor(Math.random() * specialCharacters.length));
}
return password;
}
}
Related
My use case demands me to call an sql recursively till no rows are returned for which I have written the below code which due to async nature doesn't work as expected.
The piece of code which does this invocation is:
let Response = await getData(userId);
async function getData(userId) {
console.log("Invoking Get Data Function");
let arrayOfUserId = [userId];
let fetchMore = true,
j = 1;
let keyWithQoutes = -1;
return new Promise((resolve, reject) => {
do {
console.log(arrayOfUserId, j)
j++;
if (arrayOfUserId.length > 0) {
keyWithQoutes = arrayOfUserId.map((it) => {
return `'${it}'`;
});
}
const sql = ` Select userId from USER where reportingTo in (${arrayOfUserId})`;
console.log(' SQL Query ', sql);
con.query(sql, [], async(error, response) => {
if (error) {
fetchMore = false;
reject(error);
}
console.log(
" Response for ",
userId,
response,
response.length
);
if (response.length == 0) {
fetchMore = false;
resolve(arrayOfUserId);
}
else {
for (let i = 0; i < response.length; i++) {
console.log(response[i].userId);
arrayOfUserId.push(response[i].userId);
}
}
});
} while (fetchMore);
});
}
Hi I have a for loop in my node js application which calls an async function. I want to check a value and decide whether a customer is found or not. But the loop iterates until the last element. Hence my error loop is not working. I want the loop to check the response and then iterate the next loop.
for loop:
for (let i = 0; i < customerlookupresponse.data.length; i++) {
var customer = customerlookupresponse.data[i];
if (customer != undefined) {
console.log("customer.id :: " + customer.id)
var accountlookUpData = {
customerId: customer.id
};
customerAccountLookUpRequest(accountlookUpData).then(data => {
console.log("----" + i + " -- " + data);
if (data && data.status === 1) {
resolve(data);
return;
}else{
reject({
status: 404,
message: "Customer not found"
});
return;
}
});
} else {
reject({
status: 404,
message: "Customer not found"
});
return;
}
}
the async function:
async function customerAccountLookUpRequest(customerLookUpData) {
var accountLookUp = config.app.url;
let data = await axios.get(accountLookUp).then(accountLookUpResult => {
for (i = 0; i < accountLookUpResult.data.length; i++) {
var requestaccount = accountLookUpResult.data[i].accountNumber;
if (requestaccount == customerLookUpData.lookupAccount) {
accountLookUpResult.data[i].customerId = customerLookUpData.customerId;
accountLookUpResult.data[i].status = 1;
return accountLookUpResult.data[i];
}
}
});
return data;
}
I am new to node js and trying to understand the concept of async await. Please help.
An async function waits for a Promise to return. The function that has the loop should be declared as async and the customerAccountLookUpRequest function should return a promise. Then use the await operator to call the function. Simple example:
class some_class {
constructor() {
}
async my_loop() {
let _self = this;
for (let i = 0; i < customerlookupresponse.data.length; i++) {
let data = await _self.customerAccountLookUpRequest(accountlookUpData);
console.log("----" + i + " -- " + data);
}
}
customerAccountLookUpRequest(customerLookUpData) {
return new Promise((resolve, reject) => {
axios.get(accountLookUp).then(accountLookUpResult => {
resolve(accountLookUpResult);
});
});
}
}
I have the following function involving mongoose:
let username = userObject.username;
Purchase.find({
account: username,
fufilled: true
})
.populate("keys")
.exec(function(err, foundPurchases) {
if (err) {
return inStockItems;
} else {
if (foundPurchases.length === 0) {
return inStockItems;
} else {
// these lists will be a list of IDs of game detail entries in the database
let listOfReceivedIds = foundPurchases.keys.map(obj => obj.game);
for (let i = 0; i < inStockItems.length; i++) {
if (inStockItems.length <= minimum) {
return inStockItems;
}
let currentProductAnalysing = inStockItems[i];
if (listOfReceivedIds.includes(currentProductAnalysing._id)) {
console.log("removing product");
inStockItems.splice(i, 1);
}
}
return inStockItems;
}
}
});
I am running the function like the following, which returns undefined
inStockItems = function_name(inStockItems, userObject, amount);
How can I rewrite the function so that the function returns the value of inStockItems and not undefined. Thanks.
.exec in Mongoose returns a promise of the query result if you don't give it a callback. Your function here needs to be calling .exec() and changing its return value to return something different from the function like this:
async function function_name(inStockItems, userObject, amount) {
const foundPurchases = await Purchase.find({
account: username,
fufilled: true
})
.populate("keys")
.exec();
if (foundPurchases.length === 0) {
return inStockItems;
} else {
let listOfReceivedIds = foundPurchases.keys.map(obj => obj.game);
for (let i = 0; i < inStockItems.length; i++) {
if (inStockItems.length <= minimum) {
return inStockItems;
}
let currentProductAnalysing = inStockItems[i];
if (listOfReceivedIds.includes(currentProductAnalysing._id)) {
console.log("removing product");
inStockItems.splice(i, 1);
}
}
return inStockItems;
}
}
The other alternative would be to pass a callback parameter to your function and call it from the exec() callback but promises are generally cleaner to work with.
When looping through an array to find if the array contains a word that I am looking for, the loop always returns 'false' when if I console.log out the what is being compared I can clearly see that the word I am looking for (collectionNameLookingFor) is in the array (collectionNameArray) so it should return true.
function checkCollectionNames(arrayOfCollections, collectionName) {
for (let i = 0; i < arrayofCollections.length; i++) {
if (arrayOfCollections[i] === collectionName) {
return true;
}
}
return false;
}
function saveContentToDb(req, res) {
const db = getDb();
const pageDetails = req.body;
let saveType;
db.db(pageDetails.databaseName).listCollections().toArray((error, collections) => {
if (error) {
throw error;
} else {
collections.map(collection => (collection.name)).forEach(collectionNameArray => {
const collectionNameLookingFor = req.body.page;
const check = checkCollectionNames(collectionNameArray, collectionNameLookingFor);
console.log('===========Looking to see if it is true or false==========');
console.log(check);
console.log(`Name of collection in Database: ${collectionNameArray} ::: ${collectionNameLookingFor}`);
console.log('==========================================================');
if (check === true) {
saveType = 'updated';
console.log(`saveType = ${saveType}`);
} else {
saveType = 'created';
console.log(`saveType = ${saveType}`);
}
});
}
});
}
You might need to check against collectionName, because that is the parameter you hand over, beside arrayOfCollections, instead of the array itself.
function checkCollectionNames(arrayOfCollections, collectionName) {
for (let i = 0; i < arrayOfCollections.length; i++) {
if (arrayOfCollections[i] === collectionName) {
return true;
}
}
return false;
}
Short Version:
function checkCollectionNames(arrayOfCollections, collectionName) {
return arrayOfCollections.includes(collectionName);
}
This question already has answers here:
Async/Await Class Constructor
(20 answers)
Is it bad practice to have a constructor function return a Promise?
(5 answers)
Closed 4 years ago.
I have used a class for fetching all data to store in a one object. But the object is undefined after running successfully its seems that data is stored in object(Alloptions).
I have tried but can not find sutiable way of doing
router.get('/:category', (req, res) => {
let AllOptions;
let cat4;
AllOptions = new GetAllOptions(); //show undefined
let category = req.params.category.replace(/-/g, ' ')
console.log(AllOptions)
for (i = 0; i < AllOptions.categories.length; i++) {
console.log(AllOptions.categories[i].categoryName.replace(/-/g, ' ').toLowerCase())
console.log(category)
if (AllOptions.categories[i].categoryName.replace(/-/g, ' ').toLowerCase() == category) {
cat4 = AllOptions.categories[i].categoryId - 1
}
}
})
Class object
class GetAllOptions {
constructor() {
this.categories = {};
this.languages = {};
this.getJobCategories();
}
async getJobCategories() {
await Category.getAllCategories((err, response) => {
if (err) {
//?? how error flash dont know
return res.json({
error: ERROR_MSG,
});
}
if (response.length > 0) {
for (let i = 0; i < response.length; i++) {
this.categories[response[i].categoryId] =
response[i];
}
for (let i = 0; i < response.length; i++) {
this.categoriesNames[response[i].categoryName] =
response[i];
}
}
})
this.getJobLanguages();
}
async getJobLanguages() {
await Category.getAllLanguages((err, response) => {
if (err) {
//?? how error flash dont know
return res.json({
error: ERROR_MSG,
});
}
if (response) {
for (let i = 0; i < response.length; i++) {
this.languages[response[i].languageId] =
response[i];
console.log(this.languages[response[i].languageId])
}
for (let i = 0; i < response.length; i++) {
this.languagesNames[response[i].languageName] =
response[i];
}
}
})
}
}
I want to wait until class run completed and fetch all data but here showing undefined
you can construct your GetAllOptions object asynchronously :
constructor (async_param) {
if (typeof async_param === 'undefined') {
throw new Error('Cannot be called directly');
}
}
static async build () {
var async_result = await getJobCategories()();
return new myClass(async_result);
}