nodejs issue with undefined promise nodejs using Q - node.js

I've been wrappingmind over async and sync functions as a php developer ive never had to worry about this much. so my issue is this
i have a function
function loadPartnerInventory(args,itemIds,offers,offer) {
var deferred = Q.defer();
offers.loadPartnerInventory(args, function(err, items) {
var checkItems = [];
var len = items.length;
for(var i = 0; i < itemIds.length; i++) {
for(var j = 0; j < items.length; j++) {
if (itemIds[i] == items[j].id){
//console.log('Pushed: ' + items[j].name);
checkItems.push({
itemname: items[j].market_name,
market_hash_name: items[j].market_hash_name,
steamid: offer.steamid_other,
tradeofferid : offer.tradeofferid
});
}
}
}
deferred.resolve(checkItems);
});
return deferred.promise;
}
function loadMyInventory(args,itemIds_g,offers,offer) {
var deferred = Q.defer();
offers.loadMyInventory(args, function(err, itemsg) {
var checkItems_g = [];
var len = itemsg.length;
for(var i = 0; i < itemIds_g.length; i++) {
for(var j = 0; j < itemsg.length; j++) {
if (itemIds_g[i] == itemsg[j].id){
console.log('Pushed: ' + itemsg[j].name);
checkItems_g.push({
itemname: itemsg[j].market_name,
market_hash_name: itemsg[j].market_hash_name,
steamid: offer.steamid_other,
tradeofferid : offer.tradeofferid
});
}
}
}
deferred.resolve(checkItems_g);
});
return deferred.promise;
}
function getPartnerInventory(offers, offer, itemIds, itemIds_g) {
var p1 = loadPartnerInventory({
partnerSteamId: offer.steamid_other,
appId: 730,
contextId: 2
},itemIds,offers,offer);
var p2 = loadMyInventory({appId: 730, contextId: 2},itemIds_g,offers,offer);
return Q.all(p1, p2).spread(function(checkItems, checkItems_g) {
return {
checkItems: checkItems,
checkItems2: checkItems_g
};
});
}
im doing this to get results, but somehow the second prommiss is undefined and i dont understand why.
getPartnerInventory(offers,offer,itemIds,itemIds_G).then(function(response) {
console.log(response);
//console.log(response);
});
checkitems returns correctly yet checkitems 2 is undefined.
cosole log is :
{ checkItems:
{ itemname: 'Operation Breakout Weapon Case',
market_hash_name: 'Operation Breakout Weapon Case',
steamid: '76561198245431424',
tradeofferid: '859881697' },
checkItems2: undefined }
Pushed: Glock-18 | Wraiths
as can see it its undiefined but seems to add item after its done

You cannot resolve the same promise twice. You should wrap both methods in separate promises and then use Q.all(), which will return a new promise to be resolved only after both promises have been successfully resolved. For example:
function mapOfferItem(item, offer) {
return {
itemname: item.market_name,
market_hash_name: item.market_hash_name,
steamid: args.offer.steamid_other,
tradeofferid : args.offer.tradeofferid
};
}
function loadPartnerInventory(args) {
var deferred = Q.defer();
offers.loadPartnerInventory(args, function(err, items) {
var checkedItems = items.filter(function(item) => {
return args.itemIds.indexOf(item.id) >= 0;
}).map(function(item) {
return mapOfferItem(item, args.offer);
});
deferred.resolve(checkedItems);
});
return deferred.promise;
}
function loadMyInventory(args) {
var deferred = Q.defer();
offers.loadMyInventory(args, function(err, items) {
var checkItems = items.filter(function(item) {
return args.itemIds_g.indexOf(item.id);
}).map(function(item) {
return mapOfferItem(item, args.offer);
});
deferred.resolve(checkItems);
});
return deferred.promise;
}
function getPartnerInventory(offers, offer, itemIds, itemIds_g) {
var p1 = loadPartnerInventory({
partnerSteamId: offer.steamid_other,
appId: 730,
contextId: 2
});
var p2 = loadMyInventory({appId: 730, contextId: 2});
return Q.all([p1, p2]).spread(function(checkItems, checkItems_g) {
return {
checkItems: checkItems,
checkItems2: checkItems_g
};
});
}
You can then use the function like this:
getParentInventory(offers, offer, itemIds, itemIds_g)
.then(function(checkItems) {
console.log(checkItems);
// should print {checkItems: [...], checkItems2: [...]}
});

Related

Array is empty, no data after for loop added

I'm using redis and nodejs for the first time, without success. Trying to loop insert data but got an empty array.
const redis = require("redis");
const client = redis.createClient({
retry_strategy: function(options) {
if (options.error && options.error.code === "ECONNREFUSED") {
// End reconnecting on a specific error and flush all commands with
// a individual error
return new Error("The server refused the connection");
}
if (options.total_retry_time > 1000 * 60 * 60) {
// End reconnecting after a specific timeout and flush all commands
// with a individual error
return new Error("Retry time exhausted");
}
if (options.attempt > 10) {
// End reconnecting with built in error
return undefined;
}
// reconnect after
return Math.min(options.attempt * 100, 3000);
},
});
var data_value = {
id: '235235',
totalrv: 'WAIT',
product: 'productName2',
url: 'url2',
process: 'proc',
task: 'msg'
};
client.set("key0", JSON.stringify(data_value));
client.set("key1", JSON.stringify(data_value));
client.set("key2", JSON.stringify(data_value));
client.set("key3", JSON.stringify(data_value));
client.set("key4", JSON.stringify(data_value));
//client.get("key2", redis.print);
var logger_data = {
logger: []
};
client.keys('*', function (err, keys) {
if (err) return console.log(err);
for(var i = 0, len = keys.length; i < len; i++) {
var values_v = client.get(keys[i].toString(), function(err, val) {
// console.log(logger_data);
// data is exist ...
logger_data.logger.push(JSON.parse(val));
});
}
});
// empty data
console.log(logger_data);
I wrote 2 print data result, in the loop it's working ok, but end of function, there are no data in array.
you can call a function inside the callback if you want to print the logger_data with values outside the asynchronous callback, like this
function printLoggerData(){
console.log(logger_data);
}
client.keys('*', function (err, keys) {
if (err) return console.log(err);
for(var i = 0, len = keys.length; i < len; i++) {
var values_v = client.get(keys[i].toString(), function(err, val) {
// console.log(logger_data);
// data is exist ...
logger_data.logger.push(JSON.parse(val));
// calling the function here so that it contains the latest values
printLoggerData();
});
}
});
Ok, with help of CertainPerformance, it's now working in asynchronous.
Thank you very much ...
async function getMessage () {
var logger_data = {
logger: []
};
return new Promise(function(resolve, reject) {
client.keys('*', function (err, keys) {
if (err) return console.log(err);
for(var i = 0, len = keys.length; i < len; i++) {
var values_v = client.get(keys[i].toString(), function(err, val) {
logger_data.logger.push(JSON.parse(val));
resolve(logger_data);
});
}
});
});
}
async function main() {
let message = await getMessage();
console.log(message);
}
main();

NodeJS Callback not returning completed array outside for loop

I've got an empty object array "storing" and I'm currently pushing objects in a nested for loop. This issue is when I call the callback(null, storing) outside the for loop it returns an empty array. Should I be running a promise call? Not sure where to go from here
var params = {
TableName: USER_TABLE,
KeyConditions: {
orgid: {
ComparisonOperator: 'EQ',
AttributeValueList: [org_uuid]
},
orgkey: {
ComparisonOperator: 'EQ',
AttributeValueList: [secret_key]
}
}
};
// query table for devices tied to user
dynamodb.query(params, function(err, data) {
if (err) {
badRequest();
} else {
// check whether correct org_uuid & org_key has been passed
var checked_org = data.Items[0].org_key;
if (checked_org == secret_key) {
var storing = [];
var value = data.Items[0].read.values;
for (var x = 0; x < value.length; x++) {
var query_params = {
TableName: DEVICE_TABLE,
KeyConditions: {
device_id: {
AttributeValueList: {
S: value[x]
},
ComparisonOperator: 'EQ'
}
}
};
dynamodb.query(query_params, function(err, data) {
if (err) {
console.log(err);
} else {
for (var i = 0; i < data.Count; i++) {
storing.push(data.Items[i].device_id);
}
}
});
}
callback(null, storing)
}
}
});
}

how to return list of result from sequelizejs to grpc?

How can I return a list of users using grpc, the result is empty:
I am http://condorjs.com, to create the grpc server
class User {
getUser(ctx) {
models.users.findAll({
where: { userId: ctx.req.userId }
}).then(function(users){
// return a list of users
for (var i = 0, len = users.length; i < len; i++) {
result.push({'userId': users[i].userId, 'userName': users[i].userName);
}
return { 'users': result};
});
}
}
const options = {
'listen': '0.0.0.0:50051',
'rootProtoPath': 'protos',
};
const app = new Condor(options)
.add('user.proto', 'User', new User())
.start();
GRPC client call:
var PROTO_PATH = __dirname + '/../proto/profile.proto';
var grpc = require('grpc');
var user_proto = grpc.load(PROTO_PATH).user;
function main() {
var client = new guser_proto.User('localhost:50051',
grpc.credentials.createInsecure());
client.getUser({userId: '8888'}, function(err, response) {
console.log(response);
});
}
main();
The proto:
message UserResponse {
message User{
string userId = 1;
string userName = 2;
}
repeated User users= 1;
}
You havent received any callback method at function definition so i added a callback parameter, this callback method will be called with required parameters. You will receive data at your main method
getUser(ctx, callback) {
models.users.findAll({
where: { userId: ctx.req.userId }
}).then(function(users){
// return a list of users
for (var i = 0, len = users.length; i < len; i++) {
result.push({'userId': users[i].userId, 'userName': users[i].userName);
}
callback(null,{ 'users': result});
}.bind(this));
}
}
This will surely return your data at here
function main() {
var client = new guser_proto.User('localhost:50051',
grpc.credentials.createInsecure());
client.getUser({userId: '8888'}, function(err, response) {
console.log(response); // it will print here
});
}

How can get two collection documents and calculate points using express.js?

exports.show = = function(req, res) {
var userdata = [{
"productcode": "9563456789",
"cost": "1000"
}, {
"productcode": "8756348947",
"cost": "5600"
}]
var parameterObject = [];
Parameter.find().exec(function(err, Parameters) {
if (err) {
return handleError(res, err);
}
// i want to push Parameters[0].value to parameterObject
parameterObject.push({
pointvalue: Parameters[0].value
});
});
for (var i = 0; i < userdata.length; i++) {
Product.find({
'productcode': userdata[i].productcode
}).exec(function(err, Products) {
if (err) {
return handleError(res, err);
}
var point = 0;
if (!Products) {
point = 0;
} else if (Products[0].product.point > 0) {
point = Products[0].product.point;
}
if (point > 0) {
// here i am not getting userdata[i].cost
//parameterObject.pointvalue value also not getting
totalprice = userdata[i].cost / parameterObject.pointvalue * point;
}
});
}
};
Here i have written function for calculating totalprice. i have mentioned userdata(this is my req.body).
Expectation :
i need to store Parameters objects in some variable to access where ever i want.
i want to pass userdata object in Product.find() function
how can i calculate this
totalprice= userdata[i].cost/parameterObject.pointvalue) * point);
exports.show = = function(req, res) {
var userdata = [{
"productcode": "9563456789",
"cost": "1000"
}, {
"productcode": "8756348947",
"cost": "5600"
}]
var parameterObject = [];
Parameter.find().exec(function(err, Parameters) {
if (err) {
return handleError(res, err);
}
// i want to push Parameters[0].value to parameterObject
parameterObject.push({
pointvalue: Parameters[0].value
});
return FindProducts(parameterObject, function(data) {
console.log(data);
});
});
function FindProducts(parameterObject, callback) {
for (var i = 0; i < userdata.length; i++) {
var totalprice = 0;
findProduct(i, parameterObject, function(i, price) {
totalprice += price;
if (i <= userdata.length) {
return callback({
"userid": "myuserid",
"total": totalprice
});
}
});
}
}
function findProduct(i, parameterObject, callback) {
Product.find({
'productcode': userdata[i].productcode
}).exec(function(err, Products) {
if (err) {
return handleError(res, err);
}
var point = 0;
if (!Products) {
point = 0;
} else if (Products[0].product.point > 0) {
point = Products[0].product.point;
}
if (point > 0) {
// here you can now get the value of userdata[i].cost
// here you can now get the value of parameterObject
totalprice = userdata[i].cost / parameterObject[0].pointvalue * point;
return callback(i, totalprice);
}
});
}
};
You can use promises when you want to use the result of two functions and later use it for further computation.
In your case, you can execute the two asynchronous functions in parallel. It can look like this.
Promise.all([
asyncFunc1(),
asyncFunc2(),
])
.then(function(result){
// result is an array and has the response of the functions which is
// result[0] and result[1]
···
// you can manipulate the result of the functions here
})
.catch(function(err){
// Receives rejection/error among the Promises
···
});
Here asyncFunc1() will be your first find function
asyncFunc2() will be your second find function.
The result[0] and result[1] will be the results of the functions respectively.
Later you can use the result to do further computations.
Hope this helps.

Q Promise Nodejs how to resolve in loop

i have code written in nodejs make me confusying using Q Promises
theFunction()
.then(function(data) {
var deferred = Q.defer()
var result = [];
for(i=0; i < data.length; i++) {
secondFunc(data.item)
.then(function(data2) {
data.more = data2.item
});
result.push(data);
}
deferred.resolve(result);
deferred.promise();
});
i want data in second function inside loop can push into result
so my previous data is like this
[
{
id: 1,
item: 1,
hero: 2
},
{
id: 1,
item: 1,
hero: 2
}
]
and so like this
[
{
id: 1,
item: 1,
hero: 2,
more: {
list: 1
}
},
{
id: 1,
item: 1,
hero: 2,
more: {
list: 4
}
}
]
I've tried several ways start by entering the command
deferred.resolve (); statement in the loop and only showing 1 data
have any solution ?
Instead of a deferred.resolve() on an array which will resolve immediately, use Q.all which waits for an array of promises:
theFunction()
.then(function(data) {
var result = [];
for(var i=0; i < data.length; i++) (function(i){
result.push(secondFunc(data[i].item)
.then(function(data2) {
data[i].more = data2.item;
return data[i];
}));
})(i); // avoid the closure loop problem
return Q.all(result)
});
Or even better:
theFunction()
.then(function(data) {
return Q.all(data.map(function(item)
return secondFunc(item)
.then(function(data2) {
item.more = data2.item;
return item;
});
});
});
I know this is a older post but I've the same problem and did not found any solution. Maybe someone here find a good solution very fast.
function CompareTeamspeakClients(forumUsers) {
var promises = [];
var tsClient = new TeamSpeakClient("127.0.0.1", 10011);
tsClient.send("login", {
client_login_name: "serveradmin",
client_login_password: "M+h8YzUA"
}, function(err, response){
if (err) deferred.reject(err);
});
tsClient.send("use", {
port: 9987
}, function(err, response){
if (err) deferred.reject(err);
});
forumUsers.forEach(function(user, index){
var deferred = Q.defer();
tsClient.send("clientdbfind", ["uid"], {
pattern: user.tsid
}, function(err, response){
if (err) deferred.reject(err);
if (response) {
tsClient.send("clientdbinfo", {
cldbid: response.cldbid
}, function(err, response){
if (err) deferred.reject(err);
forumUsers[index]['tsdbid'] = response.client_database_id;
forumUsers[index]['tsnickname'] = response.client_nickname;
forumUsers[index]['tslastconnected'] = response.client_lastconnected;
deferred.resolve(forumUsers);
});
}
});
promises.push(deferred.promise);
});
console.log(promises);
return Q.all(promises);
}

Resources