I am really struggling with how to get the results of getAVPPlayerInfo() returned to the place where it is called (from the generatePlayersArray function on this line: var avpinfo = getAVPPlayerInfo(pinfo);
I've been using the code before this without generatePlayersArray() and getAVPPlayerInfo(), but the player data didn't need to be updated before. I have seen people change the line to var avpinfo = await getAVPPlayerInfo(pinfo); but that doesn't fix the problem.
How can I change this to fix the disconnect between these two functions?
// creates an order with all cart items and user info
var userNewOrder = function(charge, cart, callback) {
console.log('Saving customer ORDER for charge', charge.id);
Order.create({
cart: {
username: cart.username,
items: cart.items,
totalQty: cart.totalQty,
totalPrice: cart.totalPrice
},
customer: cart.customerID,
paymentID: charge.id,
createdOn: new Date(),
paymentStatus: 'PAID',
user: cart.username
})
.then(function(order) {
console.log('Order created!', order._id);
saveUserRegistrations(order, callback);
})
.catch(function(err) {
console.log('Error creating order', err);
callback(err);
});
};
// manipulate the data to prepare for registration data
var saveUserRegistrations = function(order, callback) {
console.log('Saving registrations from order', order.id);
//put cart items into array of objects
var registrations = generateRegistrationsArray(order);
// console.log("Registrations ",registrations);
var paymentId = order.paymentID;
var userobject = order.user;
// add paymentid to arrays
for (var i in registrations) {
registrations[i].paymentID = paymentId;
registrations[i].users = userobject;
for (var x in registrations[i].players) {
console.log(registrations[i].players[x]);
}
}
console.log(
'Registrations with payment ID and username added',
registrations
);
saveRegistrations(registrations, callback);
};
// generates the registrations array from the cart items
var generateRegistrationsArray = function(order) {
console.log('Generating array from cart items');
var arr = [];
for (var i = 0; i < order.cart.items.length; i++) {
var players = generatePlayersArray(order.cart.items[i]);
console.log('Players: ', players);
// create registration, using new players array
arr.push({
event: order.cart.items[i].event,
field: order.cart.items[i].field,
day: order.cart.items[i].day,
division: order.cart.items[i].division,
level: order.cart.items[i].level,
group: order.cart.items[i].group,
numplayers: order.cart.items[i].numberofplayers,
price: order.cart.items[i].price,
players: players,
createdOn: new Date(),
net: null,
team: null,
notes: null,
paymentNote: null,
waiversSent: false,
reviewed: false,
active: true
});
console.log('Registrations:', arr);
}
console.log('Registrations array', JSON.stringify(arr));
return arr;
};
// generates the player array from the cart and AVP info
var generatePlayersArray = function(items) {
console.log('Generating players array from cart items');
var parr = [];
for (var i = 0; i < items.players.length; i++) {
var pinfo = {
last: items.players[i].last,
avp_id: items.players[i].avp_id
};
var avpinfo = getAVPPlayerInfo(pinfo);
console.log('AVP info returned', avpinfo);
// create registration, using new players array
parr.push({
first: avpinfo.first || items.players[i].first,
last: avpinfo.last || items.players[i].last,
email: items.players[i].email,
address: avpinfo.address || items.players[i].address,
city: avpinfo.city || items.players[i].city,
state: avpinfo.state || items.players[i].state,
zip: avpinfo.zip || items.players[i].zip,
country: items.players[i].country,
phone: avpinfo.phone || items.players[i].phone,
signed: false,
sandbagger: false,
waivers: [],
createdOn: new Date(),
adult: avpinfo.adult || items.players[i].adult,
avp_id: items.players[i].avp_id,
ranking: items.players[i].ranking,
overallRanking: items.players[i].overallRanking,
shirt_size: items.players[i].shirtSize
});
console.log(parr);
}
console.log('Players array', JSON.stringify(parr));
return parr;
};
// get AVP data to update player info
var getAVPPlayerInfo = function(pinfo) {
console.log('Admin AVP API begin', pinfo);
avp_id = pinfo.avp_id;
last = pinfo.last;
// GET THE AVP DATA
var options = {
uri: `http://api.volleyamerica.com/VAREST.svc/V6rHHdPO/players/${avp_id}`,
headers: {
'User-Agent': 'Request-Promise'
},
json: true // Automatically parses the JSON string in the response
};
rp(options)
.then(function(resp) {
console.log('Player has data', resp);
let avp = {};
let address = resp.Address1 || null;
if (resp.Address2) {
address += ` ${resp.Address2}`;
}
// GET AVP member data (shirt size and ranking for db)
avp.avp_id = avp_id;
avp.shirtSize = resp.AdultShirtSize;
avp.first = resp.FirstName;
avp.last = resp.LastName;
avp.email = resp.Email || null;
avp.phone = resp.HomePhone || null;
avp.address = address || null;
avp.signed = false;
avp.sandbagger = false;
avp.waivers = [];
avp.city = resp.City || null;
avp.state = resp.State || null;
avp.zip = resp.Zip || null;
// get overallRankings greater than 0
avp.overallRanking = _.pickBy(
_.get(resp, 'OverallRanking', {}),
(ranking, key) => {
return ranking > 0;
}
);
// get rankings greater than 0
avp.ranking = _.pickBy(_.get(resp, 'Ranking', {}), (ranking, key) => {
return ranking > 0;
});
let adult = null;
// if player is under 18
const birthday = moment(resp.Birthdate, 'M/D/YYYY');
age = moment().diff(birthday, 'years', false);
if (age < 18) {
avp.adult = false;
} else {
avp.adult = true;
}
console.log('AVP API SUCCESS, returning avp data ', avp);
return avp;
})
.catch(function(err) {
console.log('AVP data error', err);
});
};
//save registrations to the database
var saveRegistrations = function(registrations, callback) {
console.log('SAVING REGISTRATIONS TO DB', registrations);
// var reginfo = registrations;
Registration.collection
.insert(registrations)
.then(function(r) {
console.log('Successfully saved registrations!', r.insertedCount);
nodemailerConfirmation(registrations, callback);
})
.catch(function(err) {
console.log(err);
for (var i in err.writeErrors) {
console.log(err.writeErrors[i].errmsg);
}
callback(err.message);
});
};
// creates an order with all cart items and user info
var userNewOrder = function(charge, cart, callback) {
console.log('Saving customer ORDER for charge', charge.id);
Order.create({
cart: {
username: cart.username,
items: cart.items,
totalQty: cart.totalQty,
totalPrice: cart.totalPrice
},
customer: cart.customerID,
paymentID: charge.id,
createdOn: new Date(),
paymentStatus: 'PAID',
user: cart.username
})
.then(function(order) {
console.log('Order created!', order._id);
saveUserRegistrations(order, callback);
})
.catch(function(err) {
console.log('Error creating order', err);
callback(err);
});
};
// manipulate the data to prepare for registration data
var saveUserRegistrations = async function(order, callback) {
console.log('Saving registrations from order', order.id);
//put cart items into array of objects
var registrations = await generateRegistrationsArray(order);
// console.log("Registrations ",registrations);
var paymentId = order.paymentID;
var userobject = order.user;
// add paymentid to arrays
for (var i in registrations) {
registrations[i].paymentID = paymentId;
registrations[i].users = userobject;
for (var x in registrations[i].players) {
console.log(registrations[i].players[x]);
}
}
console.log(
'Registrations with payment ID and username added',
registrations
);
saveRegistrations(registrations, callback);
};
// generates the registrations array from the cart items
var generateRegistrationsArray = async function(order) {
console.log('Generating array from cart items');
var arr = [];
for (var i = 0; i < order.cart.items.length; i++) {
var players = await generatePlayersArray(order.cart.items[i]);
console.log('Players: ', players);
// create registration, using new players array
arr.push({
event: order.cart.items[i].event,
field: order.cart.items[i].field,
day: order.cart.items[i].day,
division: order.cart.items[i].division,
level: order.cart.items[i].level,
group: order.cart.items[i].group,
numplayers: order.cart.items[i].numberofplayers,
price: order.cart.items[i].price,
players: players,
createdOn: new Date(),
net: null,
team: null,
notes: null,
paymentNote: null,
waiversSent: false,
reviewed: false,
active: true
});
console.log('Registrations:', arr);
}
console.log('Registrations array', JSON.stringify(arr));
return arr;
};
// generates the player array from the cart and AVP info
var generatePlayersArray = async function(items) {
console.log('Generating players array from cart items');
var parr = [];
for (var i = 0; i < items.players.length; i++) {
var pinfo = {
last: items.players[i].last,
avp_id: items.players[i].avp_id
};
var avpinfo = await getAVPPlayerInfo(pinfo);
console.log('AVP info returned', avpinfo);
// create registration, using new players array
parr.push({
first: avpinfo.first || items.players[i].first,
last: avpinfo.last || items.players[i].last,
email: items.players[i].email,
address: avpinfo.address || items.players[i].address,
city: avpinfo.city || items.players[i].city,
state: avpinfo.state || items.players[i].state,
zip: avpinfo.zip || items.players[i].zip,
country: items.players[i].country,
phone: avpinfo.phone || items.players[i].phone,
signed: false,
sandbagger: false,
waivers: [],
createdOn: new Date(),
adult: avpinfo.adult || items.players[i].adult,
avp_id: items.players[i].avp_id,
ranking: items.players[i].ranking,
overallRanking: items.players[i].overallRanking,
shirt_size: items.players[i].shirtSize
});
console.log(parr);
}
console.log('Players array', JSON.stringify(parr));
return parr;
};
// get AVP data to update player info
var getAVPPlayerInfo = function(pinfo) {
console.log('Admin AVP API begin', pinfo);
avp_id = pinfo.avp_id;
last = pinfo.last;
// GET THE AVP DATA
var options = {
uri: `http://api.volleyamerica.com/VAREST.svc/V6rHHdPO/players/${avp_id}`,
headers: {
'User-Agent': 'Request-Promise'
},
json: true // Automatically parses the JSON string in the response
};
rp(options)
.then(function(resp) {
console.log('Player has data', resp);
let avp = {};
let address = resp.Address1 || null;
if (resp.Address2) {
address += ` ${resp.Address2}`;
}
// GET AVP member data (shirt size and ranking for db)
avp.avp_id = avp_id;
avp.shirtSize = resp.AdultShirtSize;
avp.first = resp.FirstName;
avp.last = resp.LastName;
avp.email = resp.Email || null;
avp.phone = resp.HomePhone || null;
avp.address = address || null;
avp.signed = false;
avp.sandbagger = false;
avp.waivers = [];
avp.city = resp.City || null;
avp.state = resp.State || null;
avp.zip = resp.Zip || null;
// get overallRankings greater than 0
avp.overallRanking = _.pickBy(
_.get(resp, 'OverallRanking', {}),
(ranking, key) => {
return ranking > 0;
}
);
// get rankings greater than 0
avp.ranking = _.pickBy(_.get(resp, 'Ranking', {}), (ranking, key) => {
return ranking > 0;
});
let adult = null;
// if player is under 18
const birthday = moment(resp.Birthdate, 'M/D/YYYY');
age = moment().diff(birthday, 'years', false);
if (age < 18) {
avp.adult = false;
} else {
avp.adult = true;
}
console.log('AVP API SUCCESS, returning avp data ', avp);
return avp;
})
.catch(function(err) {
console.log('AVP data error', err);
});
};
//save registrations to the database
var saveRegistrations = function(registrations, callback) {
console.log('SAVING REGISTRATIONS TO DB', registrations);
// var reginfo = registrations;
Registration.collection
.insert(registrations)
.then(function(r) {
console.log('Successfully saved registrations!', r.insertedCount);
nodemailerConfirmation(registrations, callback);
})
.catch(function(err) {
console.log(err);
for (var i in err.writeErrors) {
console.log(err.writeErrors[i].errmsg);
}
callback(err.message);
});
};
Check the above code.
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
});
}
I am creating an application where a user can have many rooms and each room can have many channels, here is my code when retrieving the rooms and corresponding channels:
getRooms: function (req, res) {
User.find({id: req.cookies.claver_id}).exec(function (err, result) {
if (err) {
return res.send(400);
}
rooms = result[0].rooms;
if (rooms.length === 1) {//No room defaults to ['']
return res.send(400);
}
var roomsObj = {};
var roomsArr = [];//we will place the roomsObj inside the roomsArr
var chansObj = {};
var chansArr = [];
async.each(rooms, function (roomId, cb){
roomsObj = {};
if (roomId !== '') {
Rooms.findOne({id: roomId}).exec(function (err, room){
roomName = room.name;
inviteLink = room.inviteLink;
roomsObj.name = roomName;
roomsObj.id = roomId;
roomsObj.inviteLink = inviteLink;
var channels = room.channels;
async.each(channels, function (channelId, cb) {
chansObj = {};
Channels.findOne({id: channelId}).exec(function (err, channel){
chansObj.name = channel.channelName;
chansObj.id = channelId;
chansObj.type = channel.channelType;
chansArr.push(chansObj);
cb();
});
},
function (err) {
});
});
}
cb();
}, function (err) {
roomsObj.channels = chansArr;
roomsArr.push(roomsObj);
sails.log(roomsArr);
});
});
}
It is suppose to return a javascript object with the following structure:
[ { name: "Room Name",
roomId: "Room Id",
inviteLink: "Room Invite Link",
channels: [
{
name: "Channel Name",
id: "channel Id"
}
]
}
]
But I always get an empty array because async.each(rooms, function (roomId, cb){ }) does not wait for async.each(channels, function (channelId, cb) {}) to complete, so I have empty room object. Please how do I solve this issue ?
You should call your rooms's callback loop after completing you channels loop.
You should do something like this:
getRooms: function (req, res) {
User.find({id: req.cookies.claver_id}).exec(function (err, result) {
if (err) {
return res.send(400);
}
rooms = result[0].rooms;
if (rooms.length === 1) {//No room defaults to ['']
return res.send(400);
}
var roomsObj = {};
var roomsArr = [];//we will place the roomsObj inside the roomsArr
var chansObj = {};
var chansArr = [];
async.each(rooms, function (roomId, callback1){
roomsObj = {};
if (roomId !== '') {
Rooms.findOne({id: roomId}).exec(function (err, room){
roomName = room.name;
inviteLink = room.inviteLink;
roomsObj.name = roomName;
roomsObj.id = roomId;
roomsObj.inviteLink = inviteLink;
var channels = room.channels;
var i=0;
async.each(channels, function (channelId, callback2) {
chansObj = {};
Channels.findOne({id: channelId}).exec(function (err, channel){
chansObj.name = channel.channelName;
chansObj.id = channelId;
chansObj.type = channel.channelType;
chansArr.push(chansObj);
i++;
if(i===(channels.length-1)){
i=0;
callback1();
}else{
callback2();
}
});
},
function (err) {
});
});
}
}, function (err) {
roomsObj.channels = chansArr;
roomsArr.push(roomsObj);
sails.log(roomsArr);
});
});
}
I solved it, it really was a case for promises, I used bluebird promise combined with async - the modified code:
getRooms: function (req, res) {
User.find({id: req.cookies.claver_id}).exec(function (err, result) {
if (err) {
return res.send(400);
}
rooms = result[0].rooms;
if (rooms.length === 1) {//No room defaults to ['']
return res.send(400);
}
var roomsObj = {};
var roomsArr = [];//we will place the roomsObj inside the roomsArr
var chansObj = {};
var chansArr = [];
Promise.each(rooms, function (roomId, callback1){
roomsObj = {};
if (roomId !== '') {
async.series ([
function () {
Rooms.findOne({id: roomId}).then(function (room){
roomName = room.name;
inviteLink = room.inviteLink;
roomsObj.name = roomName;
roomsObj.id = roomId;
roomsObj.inviteLink = inviteLink;
channels = room.channels;
sails.log(roomName);
})
}
]);
return Promise.each(channels, function (channelId) {
return Promise.all([
Channels.findOne({id: channelId}).then(function (channel){
chansObj = {};
chansObj.name = channel.channelName;
chansObj.id = channelId;
chansObj.type = channel.channelType;
chansArr.push(chansObj);
sails.log(chansObj);
})
]).then(function () {
sails.log('done one');
});
}).then(function () {
roomsObj.channels = chansArr;
roomsArr.push(roomsObj);
sails.log('done all');
chansArr = [];
});
}
}).then(function () {
sails.log(roomsArr);
sails.log("grand finish");
});
});
}
Thanks to everyone who contributed.
I am trying to include a module i found that will help manage users:
http://www.codeproject.com/Articles/382561/Session-Management-in-Nodejs
Ive copied the code and put it in the same directory as my server.js
I require it by doing:
var express = require('express');
var http = require('http'),
mysql = require("mysql");
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var sessionMgm = require("./sessionManagement");
Now in my socket i do this:
io.sockets.on('connection', function (socket) {
socket.on('setUserInfo', function (data) {
var sess = new Object();
sess.sessionId = socket.id;
sess.userId = data.userId;
sess.username = data.username;
sess.role = data.role;
sessionMgm.add(sess);
});
socket.on("private", function(data) {
if(data.agentName.length <= 0) {
data.agentName = 'Besökare';
}
io.sockets.in('Room_' + data.user_id).emit('updatechat', data.agentName, data.msg);
var user = sessionMgm.getSessionByUserId(data.id);
console.log('::: A socket with ID ' + user + ' connected! ::: ');
});
});
However i keep getting this error:
TypeError: Object # has no method 'getSessionByUserId'
Cant seem to figure out whats wrong, any ideas?
sessionManagement.js:
module.exports = sessionManagement;
var sessions = [];
//User roles list
var userRoles = {
Admin: "administrator",
User: "user",
Supervisor: "supervisor"
};
var sessionManagement = {
indexOf: function(sessionId) {
for(var i in sessions) {
if(sessions[i].sessionId == sessionId)
return i;
}
return null;
},
indexOfUser: function(userId) {
for(var i in sessions) {
if(sessions[i].userId == userId)
return i;
}
return null;
},
add: function(sessionData) {
sessions.push(sessionData);
},
remove: function(sessionId) {
var index = this.indexOf(sessionId);
if(index != null) {
sessions.splice(index, 1);
} else {
return null;
}
},
removeByUserId: function(userId) {
var index = this.indexOf(userId);
if(index != null) {
sessions.splice(index, 1);
} else {
return null;
}
},
getSessionById: function(userId) {
var index = this.indexOfUser(userId);
if(index != null) {
return sessions[index];
} else {
return null;
}
},
getSessionByUserId: function(sessionId) {
var index = this.indexOfUser(userId);
if(index != null) {
return sessions[index];
} else {
return null;
}
},
isAdmin: function(userId) {
var index = this.indexOfUser(userId);
if(index != null) {
if(users[index].role == userRoles.Admin) {
return true;
} else {
return false;
}
} else {
return null;
}
},
getUsersByRole: function(role) {
var usersByRole = [];
for(var i in users) {
if(users[i].role == role)
usersByRole.push(users[i]);
}
return usersByRole;
}
};
As madflow mentioned, you were missing module.exports = sessionManagement in sessionManagement.js
Then you got the error, because you were exporting sessionManagement, before initializing it. Moving the export line to the end of sessionManagement.js should fix that.
module.exports = sessionManagement; // <- you export here
...
...
...
var sessionManagement = { // and initialize here
Although sessionManagement declaration gets hoisted to the top of the module (and that's why you don't get Unexpected identifier or ReferenceError when assigning it to module.exports), it's initialization does not, so what really happens behind the scenes is something like that:
var sessionManagement; // undefined at this point
module.exports = sessionManagement; // <- you export here,
// but sessionManagement is undefined at this point
// and so will be module.exports after this line
...
...
...
sessionManagement = { // and initialize here
classroom.manager can be null on the server. So it may not come from server. I want to add it and create with my own constructor if it does not come from server. If it comes from server I want to create it with it's own data.
var mappingOption = {
create: function (classroom) {
var res = ko.mapping.fromJS(clasroom.data);
if (res.manager == undefined)
res.manager = ko.observable(new Manager());
return res;
},
'manager': {
create: function (args) {
var res = ko.mapping.fromJS(args.data);
var res2 = new Manager();
$.extend(res2, res)
return res2;
}
}
Class room model
var Classroom = function(data) {
self = this;
data = data || {};
self.manager = data.manager || new Manager();
ko.mapping.fromJS(data, {
'manager': {
function (managerData) {
return new Manager(managerData);
}
}
}, self);
};
Manager model
var Manager = function(data) {
self = this;
data = data || {};
ko.mapping.fromJS(data, {}, self);
};
Key part is the data || new Manager() section