Control not being returned from promise - javascript

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

SQL Query Recursively Async Issue

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);
});
}

for loop async in node js

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);
});
});
}
}

How to wait for a mongoose .exec() function to finish before returning?

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.

Javascript loop not returning true, when String === String

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);
}

Using Class to store all data in a object [duplicate]

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);
}

Categories