(function () { var serviceId = 'usersService'; angular.module('app').factory(serviceId, ['$q', 'myUsersDataContext', 'config', usersService]); function usersService($q, myUsersDataContext, config) { var serviceData = { allOrgsAndGroups: [], allUsers: {}, promise: null } var service = { getAllUsers: getAllUsers }; return service; // this function gets the users organisations and groups, then gets the users for each. while doing this it sets the service data cache for this so we dont have to keep loading it. // returns a promise which when resolved will contain an array [theUsersInTheOrgs, theOrgs] function setAllUsers() { var deferred = $q.defer(); // the logic for getting the organisation and all child orgs should // not really be here this should really be handled by the backend. // i wrote a service in organisations for this called getAllUsersForAllUserOrganisations // however i was pushed for time with getting it working. this is temporary. // this should handle small/medium size groups fine but it really struggles with anything over 1000 or so users. $q.all([myUsersDataContext.getOrganisationsFull(0), myUsersDataContext.getOrganisationsFull(config.groupTypeId)]).then(function (data) { var root; if(data[0].length > 0) root = data[0][0]; else root = data[1][0]; getAllDetailsAndUsers(root); function getAllDetailsAndUsers(organsation) { myUsersDataContext.getOrganisationDetails(organsation.id).then(function (details) { serviceData.orgTree = details; var allOrgs = []; getChildren(details); serviceData.allOrgsAndGroups = allOrgs; function getChildren(organisation) { allOrgs.push(organisation); if (organisation.children.length > 0) { angular.forEach(organisation.children, function (child) { getChildren(child); }); } } var promises = []; angular.forEach(serviceData.allOrgsAndGroups, function (org) { var currentOrg = $q.defer(); promises.push(currentOrg.promise); myUsersDataContext.getUsers(org.id).then(function (users) { angular.forEach(users, function (user) { // if the user is not already present in the table we need to add them if (!serviceData.allUsers[user.id]) serviceData.allUsers[user.id] = user; if (!serviceData.allUsers[user.id].orgs) serviceData.allUsers[user.id].orgs = []; if (org.type === 0) serviceData.allUsers[user.id].orgs.unshift(org); else serviceData.allUsers[user.id].orgs.push(org); }); currentOrg.resolve(); }); }); $q.all(promises).then(function () { deferred.resolve([serviceData.allUsers, serviceData.allOrgsAndGroups]); }); }); } }); serviceData.promise = deferred.promise; return serviceData.promise; } // calls setAllusers if the promise does not exist or has not yet been run, otherwise returns the promise as it should already be resolved and we can use its payload function getAllUsers() { if (serviceData.promise === null) return setAllUsers(); else return serviceData.promise; } } })();