Rally: Team status information not fetching all the needed information - javascript

I have been trying to fetch some information such as username, displayname, role and capacity depending upon iteration. The query returns some of the result for the specified project but not all for the selected iteration. I am not sure what is causing this. You can find my work so far below.
function iterationSelected(dropdown, eventArgs) {
console.log("Iteration Selected Callback");
if(table != null){
table.destroy();
}
var queryByUser = {
key: "teamDataByUser", type: "User",
fetch: 'DisplayName,UserName',
query: '(ObjectID > 0)'
};
rallyDataSource.findAll(queryByUser, queryTeamInformation);
}
function queryTeamInformation(results){
console.log(results.teamDataByUser.length);
for(var i=0;i<results.teamDataByUser.length;i++){
console.log(results.teamDataByUser[i].UserName + " " + results.teamDataByUser[i].DisplayName);
}
console.log(iterationDropdown.getSelectedName());
var queryByUserName = {
key: "teamData", type: "UserIterationCapacity",
project: null,
fetch: "Capacity,User,Role,EmailAddress,DisplayName,UserName",
query: '((Iteration.Name = ' + '"' + iterationDropdown.getSelectedName() + '") AND (Project = /project/5564891653))'
};
rallyDataSource.findAll(queryByUserName, processResults);
console.log("GH");
}
function processResults(results){
rally.forEach(results.teamData,
function(teamData) {
console.log(teamData._ref);
});
console.log(results.teamData.length);
var tableDiv = document.getElementById('table');
var config = { columns:
[{key: 'emailaddress', header: 'Team Member Email', width: 200},
{key: 'displayname', header: 'Display name'},
{key: 'username', header: 'User name'},
{key: 'role', header: 'Role'},
{key: 'cap', header: 'Capacity'}] };
if(table != null){
console.log("Got here");
table.destroy();
}
table = new rally.sdk.ui.Table(config);
for(var i=0;i<results.teamData.length;i++){
var rowInfo = {'emailaddress': results.teamData[i].User.DisplayName, 'displayname': results.teamData[i].User.UserName, 'username': results.teamData[i].User.EmailAddress, 'role' : results.teamData[i].User.Role, 'cap' : results.teamData[i].Capacity};
table.addRow(rowInfo);
}
table.display(tableDiv);
}
//========================================================================================================================
/*
* Initializes all the page elements
*/
function initPage() {
rallyDataSource = new rally.sdk.data.RallyDataSource('5410787910', '5948174836', 'false', 'true');
var config = { label : "Select an iteration " };
iterationDropdown = new rally.sdk.ui.IterationDropdown(config, rallyDataSource);
iterationDropdown.display("aDiv", iterationSelected);
}
rally.addOnLoad(initPage);

Ok - I've written an example that I think illustrates what's needed to get where you want to go. It does this by doing two queries in a queryConfig array: one for Users and another for UserIterationCapacity for the Iteration of interest. Then, in the processResults function, the code constructs three hashes:
teamMembersByTeamName: string of team members for each project, hashkey: Team/project Name
myTeamList: contains User data from Users (1st) query, selected for a Team of interest, hashkey: UserName
userIterationCapacityByUser: contains UserIterationCapacity data from 2nd query, hashkey: UserName
Finally, the code does a cross-walk by UserName to re-construct Capacity data for all TeamMembers, even if they have no capacity defined for the Sprint of interest. If this is the case, the Capacity is shown as "N/A".
You would need to customize the workspaceOID, projectOID, and myTeamSlashProjectName variables to get this to work in your environment. You will probably want to customize and tweak - it's just a rough code sample. But hopefully enough to illustrate the concept.
<!-- Copyright (c) 2012 Rally Software Development Corp. All rights reserved -->
<html>
<head>
<title>Team Capacity Summary Example</title>
<meta name="Name" content="App Example: Team Capacity Summary" />
<meta name="Version" content="1.31" />
<meta name="Vendor" content="Rally Labs" />
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.31/sdk.js"></script>
<script type="text/javascript">
var rallyDataSource = null;
var iterationDropdown = null;
var selectedIteration = "Iteration 1";
var workspaceOID = "12345678910";
var projectOID = "12345678911";
var myTeamSlashProjectName = "My Project";
var table;
function iterationSelected(dropdown, eventArgs) {
var selectedItem = eventArgs.item;
selectedIteration = eventArgs.value;
runMainQuery();
}
function runMainQuery() {
var queryConfig = [];
var capacityQueryString = '((Iteration.Name = ' + '"' +
selectedIteration +
'") AND (Project.ObjectID = "' +
projectOID +
'"))';
console.log(capacityQueryString);
queryConfig[0] = {
key: "usercapacities",
type: "UserIterationCapacity",
fetch: "Capacity,User,Role,EmailAddress,DisplayName,UserName",
query: capacityQueryString
};
queryConfig[1] = {
type: "users",
key: "userdata",
fetch: "UserName,EmailAddress,DisplayName,UserName,UserPermissions,Project,Role,Name,TeamMemberships,Project,Name"
};
rallyDataSource.findAll(queryConfig, processResults);
}
function processResults(results) {
// Populate a hash of team members by team name
var teamMembersByTeamName= new Array();
for (i=0;i<results.userdata.length;i++){
myUser = results.userdata[i];
myUserName = myUser.UserName;
myEmailAddress = myUser.EmailAddress;
myDisplayName = myUser.DisplayName;
myRole = "N/A";
if (myUser.TeamMemberships) {
myTeamMemberships = myUser.TeamMemberships;
for (j=0;j<myTeamMemberships.length;j++) {
thisTeam = myTeamMemberships[j];
thisTeamName = thisTeam.Name;
if (!(thisTeamName in teamMembersByTeamName)) {
teamMembersByTeamName[thisTeamName] = [];
}
var dataToPush = new Array();
dataToPush["UserName"] = myUserName;
dataToPush["EmailAddress"] = myEmailAddress;
dataToPush["DisplayName"] = myDisplayName;
dataToPush["Role"] = myRole;
dataToPush["Capacity"] = "N/A";
teamMembersByTeamName[thisTeamName].push(dataToPush);
}
}
}
// Now populate a hash of User Capacities
var userIterationCapacityByUser = new Array();
for (i=0;i<results.usercapacities.length;i++) {
thisCapacityObject = results.usercapacities[i];
thisUserName = thisCapacityObject.User.UserName;
if (!(thisUserName in userIterationCapacityByUser)) {
thisUser = thisCapacityObject.User;
thisCapacity = thisCapacityObject.Capacity;
userIterationCapacityByUser[thisUserName] = [];
var dataToPush = new Array();
dataToPush["UserName"] = thisUser.UserName;
dataToPush["EmailAddress"] = thisUser.EmailAddress;
dataToPush["DisplayName"] = thisUser.DisplayName;
dataToPush["Role"] = thisUser.Role;
dataToPush["Capacity"] = thisCapacity;
userIterationCapacityByUser[thisUserName].push(dataToPush);
}
}
// Setup and configure the table
var tableDiv = document.getElementById('tableDiv');
var tableConfig = { columns:
[{key: 'emailaddress', header: 'Team Member Email', width: 200},
{key: 'displayname', header: 'Display name'},
{key: 'username', header: 'User name'},
{key: 'role', header: 'Role'},
{key: 'cap', header: 'Capacity'}] };
if(table != null){
table.destroy();
}
table = new rally.sdk.ui.Table(tableConfig);
// Finally cross-walk team membership by correlating the data from the two hashes
// Grab team list of interest
myTeamList = teamMembersByTeamName[myTeamSlashProjectName];
for(i=0;i<myTeamList.length;i++) {
myTeamMemberData = myTeamList[i];
myUserNameFromTeamList = myTeamMemberData["UserName"];
// User has capacity information - populate data from that result set
if (myUserNameFromTeamList in userIterationCapacityByUser) {
myUserDataArray = userIterationCapacityByUser[myUserNameFromTeamList];
myUserData = myUserDataArray[0];
} // User doesn't have capacity information - populate data from user query
else {
myUserData = myTeamMemberData;
}
var myUserName = myUserData["UserName"];
var myEmailAddress = myUserData["EmailAddress"];
var myDisplayName = myUserData["DisplayName"];
var myRole = myUserData["Role"];
var myCapacity = myUserData["Capacity"];
if (myDisplayName) {
thisDisplayName = myDisplayName;
} else {
thisDisplayName = "N/A";
}
var rowInfo = {
'emailaddress': myEmailAddress,
'displayname': thisDisplayName,
'username': myUserName,
'role' : myRole,
'cap' : myCapacity};
table.addRow(rowInfo);
}
var tableDiv = document.getElementById("tableDiv");
table.display(tableDiv);
}
function onLoad() {
rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__',
'__PROJECT_OID__',
'__PROJECT_SCOPING_UP__',
'__PROJECT_SCOPING_DOWN__');
var config = {
label : "Select an iteration ",
defaultDisplayValue: selectedIteration
};
var iterationDropdown = new rally.sdk.ui.IterationDropdown(config, rallyDataSource);
iterationDropdown.display("aDiv", iterationSelected);
}
rally.addOnLoad(onLoad);
</script>
</head>
<body>
<div id="aDiv"></div>
<div id="tableDiv"></div>
</body>
</html>

Related

How to fix ' Filter Lookup by Current User using CAML

I am filtering a lookup column on SharePoint Online but I Keep on getting error if I inspect on the browser and the filtering is not working.
I have used jquery.SPServices.SPGetCurrentUser to get the Logged in user details. Then the CAML Query to filter and get the List Activity Plan.
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script
src="//cdnjs.cloudflare.com/ajax/libs/jquery.SPServices/2014.02/jquery.SPServices-2014.02.min.js"></script>
<script type="text/javascript">
let custom = {}
custom.myQuery = jQuery;
console.log(custom)
console.log($().SPServices.SPGetCurrentUser({
fieldNames: ["ID", "Name", "Title", "Email","DepartMent", "JobTitle",
"FirstName", "LastName", "UserName", "SIP Address"],
debug: false
}));
var userId = $().SPServices.SPGetCurrentUser({
fieldName: "ID",
debug: false
})
_spBodyOnLoadFunctionNames.push("loadSP")
function loadSP() {
var query = `<Query><Where><And><Eq><FieldRef Name='AssignedTo'
LookupId='TRUE'/><Value Type='Integer'>${userId}</Value></Eq><Eq>
<FieldRef Name='Status' LookupId='TRUE'/><Value
Type='Text'>Approved</Value></Eq></And></Where></Query>`;
custom.myQuery().SPServices({
operation: "GetListItems",
async: false,
listName: "Activity Plan",
CAMLQuery: query,
//CAMLQueryOptions: "<QueryOptions><ViewAttributes
Scope='RecursiveAll' IncludeRootFolder='True' /></QueryOptions>",
CAMLViewFields: `<ViewFields>
<FieldRef Name='Deliverable' />
<FieldRef Name='Task Status' />
<FieldRef Name='ID' />
</ViewFields>`,
completefunc: function (xData, Status) {
var newSites = "(none)";
var ID = "0";
console.log(xData)
$(xData.responseXML).find("z\\:row, row").each(function () {
var DeliverableLookup = $(this).attr("Deliverable");
var owId = $(this).attr("ID");
if (DeliverableLookup != '') {
var newValue = DeliverableLookup;
if (newSites.indexOf(newValue) == -1) {
newSites = newSites + "|" + newValue;
ID += '| ' + owId;
}
}
});
updateValues(newSites, ID);
}
});
}
function getField(fieldType,fieldTitle) {
var docTags = document.getElementsByTagName(fieldType);
for (var i=0; i < docTags.length; i++) {
if (docTags[i].title == fieldTitle) {
return docTags[i];
}
}
return false;
}
function updateValues(newSites, ID) {
lookupFieldText = getField('select','My Planned Tasks');
//lookupFieldId = document.getElementById(lookupFieldText.id);
$(lookupFieldText).empty();
let arrSites = newSites.split('|');
let arrId = ID.split('|');
for (let i = 0; i < arrSites.length; i++){
$(lookupFieldText).append(`<option id='${arrId[i]}'
value='${arrSites[i]}'> ${arrSites[i]} </option>`)
}
//lookupFieldText.choices = newSites;
}
function CustomAction(){
console.log("done loading")
}
</script>
I expect the lookup column My Planned Tasks to show only the Deliverables that I created and with status Approved, but instead it is returning all tasks.
Check your console logged data and see whats returning, if nothing is returning, check if your status is true and if not then your query is wrong.. Check for spaces in the query.

Updating multiple Firebase nodes from multiple Google Calendar inserts with a callback functions inside a loop

this is my first post on Stack, and I am new to creating web apps. I've done some searching and I think my issue has to do closures/forEach/let...
Found here - JavaScript closure inside loops – simple practical example
But I am struggling on incorporating that into my app and need some help please.
I am using Firebase Realtime DB where I am pushing some data and pulling the uID of that push, then I use that same data to create a Google Calendar entry. I then retrieve that eventID from Calendar and then update the corresponding database node. So this works when I create a single entry at a time. What I then did, was I added the option to send multiple entries at once (this depends on a datetime-local input). So I have put these multiple datetimes into an array and they send correctly to Firebase and to Calendar, but where my bug is, is that only the last Calendar eventID is being updated in Firebase. It seems that the for loop over the array of date runs through before calendar can get the eventID and update Firebase. This was seen due to only my last date in the array having the associated calendar eventID. So yeah I think the issue is the global variable newPushId, but I am not sure at the moment how to fix it. All this is new and struggling to understand.
Sorry it's long, I would rather leave my code in there in case someone has any tips. If people would prefer me to shorten it, I will. Thank you in advance for the assistance.
Here's my main function that runs on submit.
function sendInstantBook() {
// checkBookForm listed in services
if (checkInstantBookForm()) {
// Get variables from the form.
var address = $('#instant-book-change-address').val();
var instructor = $("#instant-book-instructor").children(":selected").attr("id");
var transmission = $("#instant-book-transmission").children(":selected").attr("id");
var duration = $("#instant-book-duration").children(":selected").attr("id");
var start0 = $('#instant-book-start0').val();
var multipleLessons;
if (getLessonTimes() !== false) {
multipleLessons = getLessonTimes();
}
multipleLessons = multipleLessons.split(',');
// var recurring, interval, frequency, count;
// if ($('#recurring-checkbox').is(":checked")) {
// recurring = true;
// interval = $('#instant-recurring-interval').val();
// frequency = $("#instant-recurring-freq").children(":selected").attr("id");
// count = $('#instant-recurring-count').val();
// } else {
// recurring = false;
// interval = false;
// frequency = false;
// count = false;
// }
var sortAsc = new Date(start0).getTime();
// var sortDes = 9999999999999 - sortAsc;
var date0 = start0.split('T')[0];
var timeStart0 = start0.split('T')[1];
var timeFinish0 = addTimes(timeStart0, duration);
var paymentType = $('input[name="instantPayment"]:checked').val();
var paid = $('input[name="instantPaymentCheck"]:checked').val();
var paymentNumber = getPaymentNumber(paymentType);
var paymentDate = getPaymentDate(paid, date0);
var email = adminStudentDetails.email;
var phoneNumber = adminStudentDetails.phoneNumber;
phoneNumber = phoneNumber.replace(/\s/g, "");
var firstName = adminStudentDetails.firstName;
var lastName = adminStudentDetails.lastName;
var studentName = firstName + ' ' + lastName;
var amount = getAmount(duration);
var tracking = getTracking(duration);
if (multipleLessons.length == 1) {
// Create JSON object With the request's details and push to server
var data = {
"address" : address,
"amount" : amount,
"booked" : true,
"calID" : false,
"cancelled" : false,
"date" : date0,
"dateSortAsc" : sortAsc,
// "dateSortDes" : sortDes,
"duration" : duration,
"email" : email,
"firstName" : firstName,
"instructor" : instructor,
"lastName" : lastName,
// "newStudent" : newStudent,
"paymentDate" : paymentDate,
"paymentType" : paymentType,
"paymentNumber" : paymentNumber,
"phoneNumber" : phoneNumber,
"prepaid" : paid,
// "recurring" : recurring,
"studentName": studentName,
"time": timeStart0 + ' - ' + timeFinish0,
"tracking": tracking,
"transmission" : transmission,
"type" : "Lesson",
};
// var recurringData = {
// "interval" : interval,
// "frequency" : frequency,
// "count" : count,
// };
// push data to firebase
dbrefLessons.push(data).then((snap) => {
newPushUid = snap.key;
// this is a global variable
});
insertCalEvent(data, updCalIdCallback);
showSnackbar();
}
else if (multipleLessons.length > 1) {
for (var i = 0; i < multipleLessons.length; i++) {
eachDate = multipleLessons[i].split('T')[0];
eachDateSortAsc = new Date(i).getTime();
eachStart = multipleLessons[i].split('T')[1];
eachFinish = addTimes(eachStart, duration);
// Create JSON object With the request's details and push to server
var dataMultiple = {
"address" : address,
"amount" : amount,
"booked" : true,
"calID" : false,
"cancelled" : false,
"date" : eachDate,
"dateSortAsc" : eachDateSortAsc,
// "dateSortDes" : sortDes,
"duration" : duration,
"email" : email,
"firstName" : firstName,
"instructor" : instructor,
"lastName" : lastName,
// "newStudent" : newStudent,
"paymentDate" : paymentDate,
"paymentType" : paymentType,
"paymentNumber" : paymentNumber,
"phoneNumber" : phoneNumber,
"prepaid" : paid,
"studentName": studentName,
"time": eachStart + ' - ' + eachFinish,
"tracking": tracking,
"transmission" : transmission,
"type" : "Lesson",
};
// push data to firebase
dbrefLessons.push(dataMultiple).then((snap) => {
newPushUid = snap.key;
});
// push to calendar
insertCalEvent(dataMultiple, updCalIdCallback);
}
}
showSnackbar();
}
}
And the calendar insert code.
function insertCalEvent(linfo, updCalIdCallback) {
// function insertCalEvent(linfo, linfoRecur, updCalIdCallback) {
// THIS WILL NEED TO CHANGE TO LOGGED IN USER RATHER THAN STUDENT DETAILS
// or change it over to organizer
var loggedInFirstName = studentDetails.firstName;
var loggedInLastName = studentDetails.lastName;
var today = new Date().toISOString();
var todayDate = today.split('T')[0];
var todayTime = today.split('T')[1].split('.')[0];
// var interval = linfoRecur.interval;
// var frequency = linfoRecur.frequency;
// var count = linfoRecur.count;
// if (interval == false) {
// interval = 0;
// frequency = 0;
// count = 0;
// }
var address = linfo.address;
var amount = linfo.amount;
var cancelled = linfo.cancelled;
var date = linfo.date;
var duration = linfo.duration;
var email = linfo.email;
var firstName = linfo.firstName;
var lastName = linfo.lastName;
var location;
var newStudent;
var instructor = linfo.instructor;
var paymentType = linfo.paymentType;
var paid = linfo.prepaid;
var transmission = linfo.transmission;
var type = linfo.type;
var phoneNumber = linfo.phoneNumber;
var time = linfo.time;
var time1 = time.split(' - ')[0];
var time2 = time.split(' - ')[1];
if (linfo.location == undefined) {
} else {
location = linfo.location;
}
if (linfo.newStudent == true){
newStudent = "NEW ";
} else if (linfo.newStudent == undefined || linfo.newStudent == false) {
newStudent = "";
}
if (paid == "Yes") {
paid = "PD ";
} else {
paid = "Owes ";
}
if (paymentType == "Instructor") {
paymentType = "Instructor ";
} else if (paymentType == "Office") {
paymentType = "Office ";
} else if (paymentType == "Pack") {
paymentType = "(input pack) ";
}
var event = {
'summary': paid + paymentType + amount + ' - ' + newStudent + transmission + ' ' + type + ' - ' + firstName + ' ' + lastName + ' - ' + address + ' - ' + phoneNumber,
'location': address,
'description': 'Lesson generated by XLR8 app. \nInstructor - ' + instructor + '\nBooked by ' + loggedInFirstName + ' ' + loggedInLastName + ' at ' + todayDate + ' - ' + todayTime + '.\nStudent email - ' + email,
'start': {
'dateTime': date + 'T' + time1 + ':00+10:00',
'timeZone': 'Australia/Brisbane'
},
'end': {
'dateTime': date + 'T' + time2 + ':00+10:00',
'timeZone': 'Australia/Brisbane'
},
// 'attendees': [
// {'email': 'simon.curran.89#gmail.com'},
// ],
'reminders': {
'useDefault': false,
'overrides': [
{'method': 'popup', 'minutes': 30}
]
},
// "recurrence": [
// "RRULE:FREQ="+ frequency + ";COUNT=" + count + ";INTERVAL=" + interval + ";"
// ],
// 'originalStartTime': date + 'T' + time1 + ':00+10:00',
// 'recurringEventId': 'recurringEventId',
// 'colourId': 10,
};
gapi.client.load('calendar', 'v3', function() {
var request = gapi.client.calendar.events.insert({
"calendarId": "primary",
"resource": event
}, function(err, event) {
if (err) {
console.log("There was an error contacting the Calendar service: " + err);
return;
} else {
console.log("Event created: %s", event.htmlLink);
}
});
request.execute(function(resp) {
// console.log(resp);
// var calID = resp.id;
return updCalIdCallback(resp.id);
});
});
}
And the callback function:
function updCalIdCallback(calID) {
var updatedCalID = {
"calID" : calID,
};
dbrefLessons.child(newPushUid).update(updatedCalID);
console.log(calID);
console.log(newPushUid);
newPushUid = '';
}

NodeJS some modules not working

I'm making a game with socket.io and nodejs, and I'm making a module called rooms.js, this module require users.js module and fiveSocket.js module
but when I call Rooms.New from the main server file, it says that fiveSocket is undefined, same problem when Rooms.New calls a users.js function, I got TypeError: Cannot read property 'getSocketIDbyId' of undefined
rooms.js:
var mysql = require('../mysql/mysql.js');
var headers = require('./headers.js');
var users = require('./users.js');
var fiveSocket = require('./sockets.js');
var Rooms = {
Obj: {},
Room: function(data) {
var room = this;
this.name = data.name;
this.users = [];
this.floorCode = data.floor;
this.description = data.desc;
this.maxUsers = data.maxUsers;
this.owner = data.owner;
this.setTime = new Date().getTime();
this.dbID = data.dbID;
this.doorx = data.doorx;
this.doory = data.doory;
this.doordir = data.doordir;
},
New: function(socketID, roomID) {
var keys = Object.keys(Rooms.Obj).length;
var id = keys + 1;
var callback = function(row) {
fiveSocket.emitClient(socketID, headers.roomData, {
title: row.title,
desc: row.description,
mapStr: row.floorCode,
doorx: row.doorx,
doory: row.doory,
doordir: row.doordir
});
var uid = users.getIdBySocketID(socketID);
users.Obj[uid].curRoom = roomID;
var rid = Rooms.getIdByDbID(roomID);
Rooms.Obj[rid].users.push(uid);
}
if(Rooms.getIdByDbID(roomID) != false) {
var room = Rooms.getIdByDbID(roomID);
var row = { title: room.name, description: room.description, floorCode: room.foorCode, doorx: room.doorx, doory: room.doory, doordir: room.doordir };
callback(row);
} else {
mysql.Query('SELECT * FROM rooms WHERE id = ? LIMIT 1', roomID, function(rows) {
if(rows.length > 0) {
var row = rows[0];
Rooms.Obj[id] = new Rooms.Room({name: row.title, floorCode: row.floorCode, desc: row.description, maxUsers: row.maxUsers, owner: row.owner, dbID: row.id, doorx: row.doorx, doory: row.doory, doordir: row.doordir});
callback(row);
}
});
}
},
removeUser: function(DBroomID, userID) {
var rid = Rooms.getIdByDbID(DBroomID);
var room = Rooms.Obj[rid];
var index = room.indexOf(userID);
if (index > -1) array.splice(index, 1);
},
Listener: function(users) {
setInterval(function(){
for(var roomID in Rooms.Obj) {
var room = Rooms.Obj[roomID];
// send users coordinates
room.users.forEach(function(uid) {
var socketID = users.getSocketIDbyId(uid);
var data = Rooms.getUsersInRoomData(roomID);
fiveSocket.emitClient(socketID, headers.roomUsers, data);
});
// unload inactive rooms (no users after 10 seconds)
var activeUsers = room.users.length;
var timestamp = room.setTime;
var t = new Date(); t.setSeconds(t.getSeconds() + 10);
var time2 = t.getTime();
if(activeUsers <= 0 && timestamp < time2) {
Rooms.Remove(roomID);
}
}
}, 1);
},
getUsersInRoomData: function(roomID) {
var room = Rooms.Obj[roomID];
var obj = {};
room.users.forEach(function(uid) {
var user = users.Obj[uid];
obj[uid] = {
username: user.username,
position: user.position,
figure: user.figure
};
});
return obj;
},
Remove: function(id) {
delete Rooms.Obj[id];
},
getIdByDbID: function(dbID) {
var result = null;
for(var room in Rooms.Obj) {
var u = Rooms.Obj[room];
if(u.dbID == dbID) var result = room;
}
if(result == null) return false;
else return result;
},
getDbIDbyId: function(id) {
return Rooms.Obj[id].dbID;
}
}
Rooms.Listener();
module.exports = Rooms;
EDIT: (if it can be helpful)
When I console.log fiveSocket on the main file
When I console.log fiveSocket on the rooms.js file
EDIT2: When I've removed var users = require('./users.js'); from fiveSocket, when I console.log it in rooms.js it works, why ?
EDIT3: I still have the problem
If you need the others modules sources:
Users.JS: http://pastebin.com/Ynq9Qvi7
sockets.JS http://pastebin.com/wpmbKeAA
"Rooms" requires "Users" and vice versa, so you are trying to perform "circular dependency".
Quick search for node.js require circular dependencies gives a lot of stuff, for example :
"Circular Dependencies in modules can be tricky, and hard to debug in
node.js. If module A requires('B') before it has finished setting up
it's exports, and then module B requires('A'), it will get back an
empty object instead what A may have intended to export. It makes
logical sense that if the export of A wasn't setup, requiring it in B
results in an empty export object. All the same, it can be a pain to
debug, and not inherently obvious to developers used to having those
circular dependencies handled automatically. Fortunately, there are
rather simple approaches to resolving the issue."
or
How to deal with cyclic dependencies in Node.js

Javascript: group JSON objects using specific key

I have the following JSON object and wanted to merge them by OrderID, making the items into array of objects:
[
{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
},
{
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}
]
and I'm wondering how in Javascript to merge the items on the same order...like this:
[{
"OrderID": "999123",
"Items": [{
"ItemCode": "DY-FBBO",
"ItemQuantity": "2",
"ItemName": "DOIY Foosball Bottle Opener > Red",
"ItemPrice": "34.95"
}, {
"ItemCode": "TED-072",
"ItemQuantity": "1",
"ItemName": "Ted Baker Womens Manicure Set",
"ItemPrice": "74.95"
}]
}]
I suggest you use javascript library like underscorejs/lazyjs/lodash to solve this kind of thing.
Here is the example on using underscorejs:
var data = [{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
}, {
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}]
var result = _.chain(data).groupBy(function (e) {
return e.OrderID;
}).map(function (val, key) {
return {
OrderID: key,
Items: _.map(val, function (eachItem) {
delete eachItem.OrderID;
return eachItem;
})
};
}).value();
Working example:
var data = [{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
}, {
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}];
var result = _.chain(data).groupBy(function (e) {
return e.OrderID;
}).map(function (val, key) {
return {
OrderID: key,
Items: _.map(val, function (eachItem) {
delete eachItem.OrderID;
return eachItem;
})
};
}).value();
document.write(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
This should do what you want it to do, but it's rather a group function than a merge function :)
You can see the result in the browser console.
var items = [
{
"OrderID":"999123",
"ItemCode":"TED-072",
"ItemQuantity":"1",
"ItemPrice":"74.95",
},
{
"OrderID":"999123",
"ItemCode":"DY-FBBO",
"ItemQuantity":"2",
"ItemName":"DOIY Foosball Bottle Opener > Red",
"ItemPrice":"34.95",
}
];
function groupBy(ungrouped, groupByProperty) {
var result = [],
getGroup = function (arr, val, groupByProperty) {
var result, j, jlen;
for (j = 0, jlen = arr.length; j < jlen; j++) {
if (arr[j][groupByProperty] === val) {
result = arr[j];
break;
}
}
if (!result) {
result = {};
result.items = [];
result[groupByProperty] = val;
arr.push(result);
}
return result;
}, i, len, item;
for (i = 0, len = ungrouped.length; i < len; i++) {
item = getGroup(result, ungrouped[i][groupByProperty], groupByProperty);
delete ungrouped[i][groupByProperty];
item.items.push(ungrouped[i]);
}
return result;
}
var grouped = groupBy(items, 'OrderID');
document.getElementById('result').innerHTML = JSON.stringify(grouped);
console.log(grouped);
<div id="result"></div>
Lodash is a great Javascript Utility library that can help you in this case. Include the latest version of lodash in your code and group the objects like this:
var mergedOrders = _.groupBy(OriginalOrders, 'OrderID');
It seems you'll have to do a function that, for each entry, will check if it match
try this :
// your array is oldArr
var newArr = []
for (var i=0;i<oldArr.length;i++){
var found = false;
for(var j=0;j<newArr.length;j++){
if(oldArr[i]["OrderID"]==newArr[j]["OrderID"]){
newArr[j]["Items"].push(oldArr[i]);
found=true;
break;
}
if(!found){
newArr.push({"OrderID" : oldArr[i]["OrderID"], "Items" : oldArr[i]});
}
}
You need to loop and create new grouped objects according to your requirement.
For an easier approach I would suggest using jquery-linq
var qOrderIds = $.Enumerable.From(myArray).Select(function(item) { return item.OrderID; }).Distinct();
var groupedList = qOrderIds.Select(function(orderId) {
return {
OrderID: orderId,
Items : $.Enumerable.From(myArray).Where(function(item) { item.OrderID === orderId}).ToArray()
};
}).ToArray();
Thank you for all your answers.
I was able to attain my goal (maybe a bit dirty and not as beautiful as yours but it worked on my end). Hoping this might help others in the future:
function processJsonObj2(dataObj, cfg) {
var retVal = dataObj.reduce(function(x, y, i, array) {
if (x[cfg.colOrderId] === y[cfg.colOrderId]) {
var orderId = x[cfg.colOrderId];
var addressee = x[cfg.colAddressee];
var company = x[cfg.colCompany];
var addr1 = x[cfg.colAddress1];
var addr2 = x[cfg.colAddress2];
var suburb = x[cfg.colSuburb];
var state = x[cfg.colState];
var postcode = x[cfg.colPostcode];
var country = x[cfg.colCountry];
var orderMsg = x[cfg.colOrderMessage];
var carrier = x[cfg.colCarrier];
delete x[cfg.colOrderId];
delete y[cfg.colOrderId];
delete x[cfg.colAddressee];
delete y[cfg.colAddressee];
delete x[cfg.colCompany];
delete y[cfg.colCompany];
delete x[cfg.colAddress1];
delete y[cfg.colAddress1];
delete x[cfg.colAddress2];
delete y[cfg.colAddress2];
delete x[cfg.colSuburb];
delete y[cfg.colSuburb];
delete x[cfg.colState];
delete y[cfg.colState];
delete x[cfg.colPostcode];
delete y[cfg.colPostcode];
delete x[cfg.colCountry];
delete y[cfg.colCountry];
delete x[cfg.colOrderMessage];
delete y[cfg.colOrderMessage];
delete x[cfg.colCarrier];
delete y[cfg.colCarrier];
var orderObj = {};
orderObj[cfg.colOrderId] = orderId;
orderObj[cfg.colAddressee] = addressee;
orderObj[cfg.colCompany] = company;
orderObj[cfg.colAddress1] = addr1;
orderObj[cfg.colAddress2] = addr2;
orderObj[cfg.colSuburb] = suburb;
orderObj[cfg.colState] = state;
orderObj[cfg.colPostcode] = postcode;
orderObj[cfg.colCountry] = country;
orderObj[cfg.colOrderMessage] = orderMsg;
orderObj[cfg.colCarrier] = carrier;
orderObj["Items"] = [ x, y ];
return orderObj;
} else {
var orderId = x[cfg.colOrderId];
var addressee = x[cfg.colAddressee];
var company = x[cfg.colCompany];
var addr1 = x[cfg.colAddress1];
var addr2 = x[cfg.colAddress2];
var suburb = x[cfg.colSuburb];
var state = x[cfg.colState];
var postcode = x[cfg.colPostcode];
var country = x[cfg.colCountry];
var orderMsg = x[cfg.colOrderMessage];
var carrier = x[cfg.colCarrier];
var itemCode = x[cfg.colItemCode];
var itemQuantity = x[cfg.colItemQuantity];
var itemName = x[cfg.colItemName];
var itemPrice = x[cfg.colitemPrice];
var item = {};
item[cfg.colItemCode] = itemCode;
item[cfg.colItemQuantity] = itemQuantity;
item[cfg.colItemName] = itemName;
item[cfg.colItemPrice] = itemPrice;
var orderObj = {};
orderObj[cfg.colOrderId] = orderId;
orderObj[cfg.colAddressee] = addressee;
orderObj[cfg.colCompany] = company;
orderObj[cfg.colAddress1] = addr1;
orderObj[cfg.colAddress2] = addr2;
orderObj[cfg.colSuburb] = suburb;
orderObj[cfg.colState] = state;
orderObj[cfg.colPostcode] = postcode;
orderObj[cfg.colCountry] = country;
orderObj[cfg.colOrderMessage] = orderMsg;
orderObj[cfg.colCarrier] = carrier;
orderObj["Items"] = [ item ];
return orderObj;
}
});
return retVal;
}

Extracting data form another section with same ID (Appcelerator)

I have the following JSON: (its simplified a bit for you)
{ returnJSON = {
studentDataVOs = {
finalGrades = (
{
grade = A;
percent = 100;
sectionid = 7744;
reportingTermId = 801;
},
{
grade = B+;
percent = 89;
sectionid = 7745;
reportingTermID = 801;
});
reportingTerms = (
{
id = 801;
title = S1;
},
{
id = 802;
title = S2;
});
sections = (
{
id = 7744;
termID = 801;
courseTitle = Physics;
courseCode = 88A;
},
{
id = 7745;
termID = 801;
courseTitle = Government;
courseCode = 90B;
});
};
};
}
I am building an app using Appcelerator Titanium that displays a table view with the data hopefully showing the following:
Physics (88A) - S1 (Grade: A, 100%)
Government (90B) - S1 (Grade: B+, 89%)
...and so on...
I have the table view set up and the following code extracts the data from the sections and puts it in the labels of the table view:
var response = JSON.parse(response);
var sections = response.returnJSON.studentDataVOs.sections;
for (i=0;i<sections.length;i++) {
var courseName = sections[i].courseTitle;
var courseCode = sections[i].courseCode;
}
What I cannot figure out is how to go about fetching the grade, and term title for each individual class. As you can see, the data for each section contains an ID and termID, which direct me to a section in the finalGrades and reportingTerms that contains the ID or termID, where I need to fetch the final grades, percents, and term titles.
Can anyone help me with this? I have been trying on and off for two days trying to figure this out...
You should create indexes for each field you've listed. It's pretty simple:
//for example you have user list
var users = [{
id : 1, email : 'user#gmail.com',
nickname : 'John'
}, {
id : 2, email : 'user#stackoverflow.com',
nickname : 'Peter'
}];
//and you need to query user by his email, id and nickname
//first, create 3 index list
var usersIdIndex = {}, usersEmailIndex = {},
usersNicknameIndex = {};
//then fill them
users.forEach(function(user){
usersIdIndex[user.id] = user;
usersEmailIndex[user.email] = user;
usersNicknameIndex[user.nickname] = user;
});
//now you can get users by any of this fields
//for example
console.log(usersIdIndex[2].nickname== 'Peter');
console.log(usersNicknameIndex['John'].email == 'user#gmail.com');
Sections -> Final Grades
In the sections list, I would pass a variable in the tablerow that I could use to query for the next set of data. You need the section id to associate the data with the data in the final grade, so I would add it to my table row.
When creating your table:
// This loop to loop through the data.
function getSections(_args){
var response = JSON.parse(response);
var sections = response.returnJSON.studentDataVOs.sections;
for (i=0;i<sections.length;i++) {
createMyRow({
courseName: sections[i].courseTitle,
courseCode: sections[i].courseCode,
sectionId: sections[i].id
});
}
}
// This function creates the rows for the table
function createMyRow(_args){
// the sectionId is now included in the tableRow and can be used later for your
// next query.
// allows the sectionId value is now can be queried when a user clicks it
// through e.rowData.
var tableRow = Ti.UI.createTableViewRow({
sectionId: _args.sectionId
});
var title = Ti.UI.createLabel({
text: _args.courseName
});
tableRow.add(title);
return tableRow;
}
var tableView = Ti.UI.createTableView();
var data = [];
function refreshTable()
data = getSections();
var rows = [];
for( var i = 0; i<data.length; i++){
rows.push(createMyRow(data[i]);
}
tableView.setData(rows);
}
// this passes the value of the sectionId so you can use it to look up your next section.
tableView.addEventListener('click', function(e){
getFinalGrades({
sectionId: e.rowData.sectionId
})
});
function getFinalGrades(_args){
var finalGrades = response.returnJSON.studentDataVOs.finalGrades
var data = [];
for (i=0;i<finalGrades.length;i++) {
if(finalGrades[i].sectionId == _args.sectionId){
data.push({
grade: finalGrades[i].grade,
percent: finalGrades[i].percent
});
}
}
return data;
}
I hacked this together rather quickly looking at some of my code examples. At the end of the getFinalGrades function, you would have an array of finalGrades that were only from sectionId you clicked.

Categories