Callback return empty array js - javascript

Here is the function with in sql queries call.
I need return callback only after all queries done.
But it return an empty array
How to return array with data after all?
`
function getUserSales(days, callback){
getUserByLastLoginDay(days, function (users) {
var userArray = [];
_.each(users, function (user) {
getMostFavoredCat(user.id, function (cat) {
if(!cat || cat.length == 0){
return false;
} else {
user.mostFavoredCat = takeMostRepeatingObj(cat);
}
getRelatedSaleByCat(user.id, user.mostFavoredCat.id, function (sales) {
user.sales = sales;
userArray.push(user)
})
})
})
callback(userArray);
})
}
`

callback function first parameter is always an error
callback(null,userArray)
you can make use of async.js for the better control flow
npm i async --save
const async = require('async');
function getUserSales(days, callback){
getUserByLastLoginDay(days, function (users) {
var userArray = [];
async.each(users, function (user, cb) {
getMostFavoredCat(user.id, function (cat) {
if(!cat || cat.length == 0){
return false;
} else {
user.mostFavoredCat = takeMostRepeatingObj(cat);
}
getRelatedSaleByCat(user.id, user.mostFavoredCat.id, function (sales) {
user.sales = sales;
userArray.push(user)
cb();
})
})
}, (err) => {
if (err) {
return callback(err);
} else {
callback(null, userArray);
}
})
})
}

I think it will Works:
function getUserSales(days, callback){
getUserByLastLoginDay(days, function (users) {
var userArray = [];
_.each(users, function (user) {
getMostFavoredCat(user.id, function (cat) {
if(!cat || cat.length == 0){
return false;
} else {
user.mostFavoredCat = takeMostRepeatingObj(cat);
}
getRelatedSaleByCat(user.id, user.mostFavoredCat.id, function (sales) {
user.sales = sales;
userArray.push(user)
})
})
callback(userArray);
})
})
}

Related

How do I await for subscribe to subscribe

I used the code below until I found out that the getConnectedUser() function takes longer than verifyUser(), so this.userUID is undefined:
this.layoutService.getConnectedUser().subscribe(
(data) => {
this.userSaml = data;
this.layoutService.connectedUser.matricule = this.userSaml.matricule;
this.layoutService.connectedUser.profil = this.userSaml.profil;
this.layoutService.connectedUser.uid = this.userSaml.uid;
this.layoutService.connectedUser.username = this.userSaml.username;
this.layoutService.connectedUser.city = this.userSaml.city;
console.log("dashboard this.layoutService.connectedUser", this.layoutService.connectedUser);
},
(err) => {
throw err;
}
);
this.userUID = this.layoutService.connectedUser.uid;
console.log("this.userUID", this.userUID);
this.adminService.verifyUser(this.userUID).subscribe(
(data) => {
this.userStatus = data[0].status;
this.userProfile = data[0].profil;
console.log("userProfile" + JSON.stringify(data[0].profil));
this.userExists = true;
},
(err) => {
this.userExists = false;
}
);
So, I wanted to make sure that the getConnectedUser subscribe is completed to call the second one, I changed my code and added the .add method just like that:
this.layoutService.getConnectedUser().subscribe(
(data) => {
this.userExistsRefog = true;
this.userSaml = data;
this.layoutService.connectedUser.matricule = this.userSaml.matricule;
this.layoutService.connectedUser.profil = this.userSaml.profil;
this.layoutService.connectedUser.uid = this.userSaml.uid;
this.layoutService.connectedUser.username = this.userSaml.username;
this.layoutService.connectedUser.city = this.userSaml.city;
console.log("home connectedUser", this.layoutService.connectedUser);
},
(err) => {
this.userExistsRefog = false;
throw err;
}
).add(() => {
this.userUID = this.layoutService.connectedUser.uid;
console.log("this.userUID", this.userUID);
this.adminService.verifyUser(this.userUID).subscribe(
(data) => {
this.userStatus = data[0].status;
this.userProfile = data[0].profil;
console.log("userProfile" + JSON.stringify(data[0].profil));
this.userExists = true;
},
(err) => {
this.userExists = false;
}
);
});
I want to learn how to use the Async/await way for this example and what is the best approach to adopt for similar functionality ? Thanks
mainly you have two ways.
1.write the method call verifyuser() inside the subscription of getconnecteduser() method.in that way you will never get a null value.
2.you can use promises instead of observable subscription. then use async/await to delay the execution of the method.
async userTasks() {
const usersDetails = await this.layoutService.getConnectedUser().toPromise();
this.layoutService.connectedUser.uid = usersDetails.uid;
this.adminService.verifyUser(this.userUID).subscribe(
(data) => {
this.userStatus = data[0].status;
this.userProfile = data[0].profil;
console.log("userProfile" + JSON.stringify(data[0].profil));
this.userExists = true;
},
(err) => {
this.userExists = false;
}
);
}

MongoDB Find queries slow while updating/inserting schema

I'm doing a big loop once a day - which updating existing documents in the database (and also inserting new documents).
this loop get executed in a separate server ( prevents from the main server to be slow ), but the main problem is that all the find queries on the Data base (while the loop is executed) are very slow (the loop slows it down significantly).
This is a very big issue in my website ( this loop must be executed once a day ) and iv'e been trying to find a solution online - but i couldn't manage to find something.
Is there any way to prevent the find queries from being so slow while inserting/updating the database??
uploadProductsManually = async (name, products, map, valuesMap) => {
return new Promise(async function (resolve, reject) {
const company = await Company.findOne({ name }).exec();
if (!company) return reject(new errors.NotFound("Company not found"));
const rows = products;
const parsedRows = [];
const findCorrectKey = (key) => {
const correctKey = key.trim();
if (productFields[correctKey]) return productFields[correctKey];
const category = map.find((item) => {
return item.options.some((option) => {
return option.trim().toLowerCase() === correctKey.toLowerCase();
});
});
const categoryName = category && category.name;
return productFields[categoryName];
};
const hashProductValues = (product) => {
let valueToHash;
if (product.productId) {
valueToHash = product.productId;
} else if (product.certificateId) {
valueToHash = product.certificateId;
} else {
valueToHash = JSON.stringify(
product.size + product.color
);
}
return base64encode(valueToHash);
};
rows.forEach(function (row, i) {
var newProduct = {};
for (var key in row) {
var val = row[key];
if (val) {
let normalizedKey = findCorrectKey(key);
if (normalizedKey) {
newProduct[normalizedKey] = val;
}
let normalizedValue = normalizeValue(normalizedKey, val,valuesMap);
newProduct[normalizedKey] = normalizedValue;
}
}
newProduct.channels = [];
if (newProduct.productId) {
parsedRows.push(newProduct);
}
});
fetchProducts();
function fetchProducts() {
Product.find({ company: company._id }).exec(function (err, products) {
if (err) console.log(err);
var map = {};
if (products) {
products.forEach(function (product) {
const productIdentifier = hashProductValues(product);
map[productIdentifier] = product;
if (product.productStatus == "manual") {
// product.isAvailable = false;
// product.save();
} else {
product.status = "deleted";
product.save();
}
});
}
mergeData(map);
});
}
async function mergeData(map) {
let created = 0;
let updated = 0;
let manual = 0;
async.each(
parsedRows,
function (row, callback) {
const productIdentifier = hashProductValues(row);
let product = map[productIdentifier];
if (product) {
map[productIdentifier] = undefined;
Product.findByIdAndUpdate(id, { $set: updatedProduct }, function (
err,
updatedProd
) {
if (err) {
// errors.push(productIdentifier);
console.log("err is:", err);
}
updated++;
callback();
});
} else {
row = new Product(row);
row.save(function (err) {
if (err) {
// errors.push(productIdentifier);
console.log(err);
}
created++;
callback();
});
}
},
(err) => {
if (err) return reject(err);
Company.findByIdAndUpdate(
company._id,
{ lastUpdate: new Date() },
function (err, comp) {
if (err) console.log(err);
}
);
console.log(
`Created: ${created}\nUpdated: ${updated} \manual: ${manual}`
);
resolve({
created,
updated,
manual,
errors,
});
}
);
}
});
};

mysql node.js query error(undefined)? how to fix it

The problem is that when the second request is executed, it returns undefined, i.e. for some reason, it does not see the result of the second request. It should work like this: We make the first request, and if there are less than two lines, then we execute the second request. What could be the error? how to fix it
let arr = [name1, name2 /* ... */];
let ipObject = { Objects: [] };
arr.forEach(function(elem, index) {
connection.query("select 1 from i.goa where object_name = ?", elem, (err, rows) => {
// console.log (rows.length);
if (rows.length < 2) {
// console.log (elem);
connection.query(
"SELECT ip_adress FROM i.gs where server_kod=(SELECT server_kod FROM i.gol where object_kod =(SELECT object_kod FROM i.goa where object_name=?))",
elem,
(err, rows2) => {
console.log(elem);
console.log(rows2);
if (undefined !== rows2 && rows2.length > 0) {
// if(rows2.length>0 ){
ipObject.Objects.push({ objectName: elem, serverIp: rows2[0].ip_adress });
}
i++;
if (i > count) {
cb(JSON.stringify(ipObject));
console.log(JSON.stringify(ipObject));
// fs.writeFileSync('e.json',JSON.stringify(ipObject),'utf8');
}
},
);
} else if (rows.length >= 2) {
ipObject.Objects.push({ objectName: elem, serverIp: "ошибка" });
cb(JSON.stringify(ipObject));
}
});
});
You're probably bumping into asynchronicity issues here.
Refactoring things to use async/await and Promise.map(), maybe this is closer to what you want:
function queryP(connection, query, params) {
return new Promise((resolve, reject) => {
connection.query(query, params, (err, result) => {
if (err) {
return reject(err);
}
resolve(result);
});
});
}
async function queryForName(connection, objectName) {
const rows = await queryP(connection, "select 1 from i.goa where object_name = ?", objectName);
if (rows.length >= 2) {
return { objectName, serverIp: "ошибка" };
}
const rows2 = await queryP(connection, "SELECT ip_adress FROM i.gs where server_kod=(SELECT server_kod FROM i.gol where object_kod =(SELECT object_kod FROM i.goa where object_name=?))", objectName);
if (rows2.length > 0) {
return { objectName, serverIp: rows2[0].ip_adress };
}
return { objectName, serverIp: "???" };
}
async function queryForNames(connection, names) {
return {
Objects: await Promise.all(names.map((name) => queryForName(connection, name))),
};
}
// could as well be `const resultObject = await queryForNames(...)` if you're calling this from an async function.
queryForNames(connection, [name1, name2]).then((resultObject) => {
console.log(resultObject);
});

Calling async.waterfall within async.series function not executing async.series callback function

I would like to call use async waterfall function within a async series function. looks like parallel functions are executed but final callback function of async series does not seem to be executed. I get the results of the instances of the function which is called with different arguments in series function but cannot have the line executed for some reason.
➜ lib git:(jumpstart-compare) ✗ node aws-ecs.compare.js
Data 1f701a9754eb22ce8f0dcdb4c1b0b366a51ade9a
Data 4cc27bcc2a8482478ac2e5c0cf3ac1babe153374
var AWS = require('aws-sdk');
const async = require('async')
const _ = require('lodash');
AWS.config.update({
region: 'us-east-1'
});
const ecs = new AWS.ECS();
getClusterSha = (clustername,app,callback) => {
const ListServices = (callback) => {
let params = {
cluster: clustername
}
//console.log('list tasks executed')
ecs.listServices(params, (err, data) => {
if (err) {
callback(err)
} else {
let dataObj = {
data: data,
cluster: clustername
}
callback(null,dataObj)
}
})
}
const getService = (arg1, callback) => {
let appname = app
arg1.cluster
let finaldata = arg1.data.serviceArns.filter((elem)=>{
if(elem.indexOf(appname) != -1){
return elem
}
});
//console.log('finaldata: ',finaldata)
if(finaldata.length > 0){
callback(null,finaldata.toString().split('/')[1])
}else{
callback('No app with name: '+appname+' found!')
}
}
const describeService = (arg2, callback) => {
let params = {
services: [arg2],
cluster: clustername
}
ecs.describeServices(params, (err, data) => {
if (err) {
callback(err)
} else {
// console.log(data)
callback(null,data.services[0].taskDefinition.split('/')[1])
}
})
}
const describeTaskDef = (arg3, callback) => {
let params = {
taskDefinition: arg3
}
ecs.describeTaskDefinition(params, (err, data) => {
if (err) {
callback(err)
} else {
//console.log(data.taskDefinition.containerDefinitions[0].image.split('/')[1].split(':')[1])
finaldata = data.taskDefinition.containerDefinitions[0]
.image.split('/')[1]
.split(':')[1]
callback(null,finaldata)
}
})
}
// const githubCall = (arg4,callback) => {
// console.log('https://github.com/Jumpstart-Auto'+'/'+app+'/commit/'+arg4)
// callback(null,'https://github.com/Jumpstart-Auto'+'/'+app+'/commit/'+arg4)
// }
async.waterfall([
ListServices,
getService,
describeService,
describeTaskDef,
], (err, data) => {
if (err) {
console.log('Error', err)
callback(err)
} else {
console.log('Data', data)
callback(null,data)
}
})
}
compareSha = (clustername1,clustername2,app) => {
async.series([
getClusterSha(clustername1,app,(data)=>{return data}),
getClusterSha(clustername2,app,(data)=>{return data})
], (err,result)=>{
console.log(err,result)
})
}
compareSha('dev','staging','jamobot',function(err,data){
console.log(data)
})
//module.exports = getShaCluster
changing async.series to following fixed the problem.
async.waterfall([
ListServices,
getService,
describeService,
describeTaskDef,
], (err, data) => {
if (err) {
console.log('Error', err)
callback(err)
} else {
console.log('Data', data)
callback(null,data)
}
})
}
compareSha = (clustername1,clustername2,app,cb) => {
async.series([
function(callback){
getClusterSha(clustername1,app,callback)
},
function(callback){
getClusterSha(clustername2,app,callback)
},
], (err,result)=>{
if(err){
cb(err)
}else{
cb(null,result)
}
})

Get result from second function in nodejs

write node js script and have next problem. How i get result from clientSession function
var User = function() {}
User.prototype.get_current_user = function (cookie) {
var cookieManager = new co.cookie(cookie);
var clientSession = new redis.createClient();
var respons=clientSession.get("sessions/"+cookieManager.get("PHPSESSID"), function(error, result) {
try {
if(result != null){
var session=JSON.parse(result);
if(session.current_user_ID>=1) {
return session.current_user_ID;
}
} else {
return "session does not exist";
}
} catch (error) {
return "error : "+error;
}
});
return respons;
}
module.exports = new User();
Function call
var User=require('user');
var user_data=User.get_current_user(ws.upgradeReq.headers["cookie"]);
console.log(user_data); // return null. Null it's wrong answer :)
Who has any ideas?
From what I see get_current_user is an async function. So if you want to the current_user_ID, you will need to pass in a function to be used as a callback.
User.prototype.get_current_user = function (cookie, callback) {
var cookieManager = new co.cookie(cookie);
var clientSession = new redis.createClient();
clientSession.get("sessions/"+cookieManager.get("PHPSESSID"), function(error, result) {
try {
if(result != null){
var session=JSON.parse(result);
if(session.current_user_ID>=1) {
callback(null, session.current_user_ID);
}
} else {
callback("session does not exist");
}
} catch (error) {
callback("error : "+error);
}
});
}
Then use it as
User.get_current_user(ws.upgradeReq.headers["cookie"], function(err, userId) {
if(!err) {
console.log(userId);
}
});

Categories

Resources