0

This is my first attempt at attempting to chain multiple finds together. The debug running shows that all the code executes correctly but there is a delay in receiving the users array back and therefore unable to present the data back.

The concept is a user may belong to multiple organizations, and there may be more than one user (other than the current user) that may belong to organizations. The function is trying to receive all users for all the organizations the current user belongs to.

 getUserOrganizationsUsers: function (userId) {
    var users = [];

    sails.log.info('Getting the current users organizations [' + userId + ']');
    return UserOrganization.find({ user_id: userId, deleted: null })
      .populate('organization_id', { deleted: null })
      .populate('user_id', { deleted: null })
      .then(function (userorganization) {
        return userorganization;
      })
      .then(function (userorgs) {
          /* From all the organizations I want to get all the users from those organizations */
        _.forEach(userorgs, function (userorg) {
          UserOrganization.find({ organization_id: userorg.organization_id.id })
            .populate('organization_id', { deleted: null })
            .populate('user_id', { deleted: null })
            .then(function (otherusrs) {
              _.forEach(otherusrs, function (otherusr) {
                sails.log.info('other userss each loop ');
                 var users = _.find(otherusrs, {id: otherusr.organization_id.id});
                users.push(users);
              })
            })
        });

        return Q.when(employees);
      })
  },

Organization.js

module.exports = {
  attributes: {
    companyName: {
      type: 'string',
      required: true
    },
  Address: {
      type: 'string'
    },
 ABN: {
      type: 'string'
    },
  City: {
      type: 'string'
    },
  contactNumber: {
      type: 'string'
    },
  country: {
      type: 'string'
    },
    icon: {
      type: 'string'
    },
      users: 
{    collection: 'userorganization',
  via : 'user_id'
},
      deleted: {
      type: 'date',
      defaultsTo: null
    },
    toJSON: function () {
      var obj = this.toObject();
      obj = _.pick(obj, Organization.publicFields);
      return obj;
    }
  },

  editableFields: [
    'companyName',
 'users'
 //   'industries'
  ],

  publicFields: [
    'id',
    'companyName',
 'users'
  ],

  };

UserOrganization.js

module.exports = {

  attributes: {
    organization_id: {
      model : 'organization',
      required: true
    },
  user_id: {
      model: 'user',
      required: true
    },
  organizationRole: {
      type: 'string',
      required: true
    },
     deleted: {
      type: 'date',
      defaultsTo: null
    },
    toJSON: function () {
      var obj = this.toObject();
      obj = _.pick(obj, UserOrganization.publicFields);
      return obj;
    }
  },

  editableFields: [
    'organization_id',
    'user_id',
    'organizationRole',
  ],

  publicFields: [
    'id',
    'organization_id',
    'user_id',
    'organizationRole'
  ],

};

and the user.js

var bcrypt = require('bcrypt-nodejs');

module.exports = {
  attributes: {
    email: {
      type: 'email',
      required: true,
      unique: true
    },
    password: {
      type: 'string',
      required: true
    },
      firstName: {
      type: 'string'
    },
    lastName: {
      type: 'string'
    },
     verified: {
      type: 'boolean',
      defaultsTo: false
    },
    organizations: 
{    collection: 'userorganization',
  via : 'user_id'
},     deleted: {
      type: 'date',
      defaultsTo: null
    },
    fullName: function () {
      return this.firstName + ' ' + this.lastName;
    },
    toJSON: function () {
      var obj = this.toObject();
      obj = _.pick(obj, User.publicFields);
      return obj;
    }
  },

  // TODO: Add initialFields

  editableFields: [
    'password',
    'email',
     'firstName',
    'lastName',
    'organizations'],

  publicFields: [
    'id',
    'email',
    'verified',
      'firstName',
    'lastName',
      'fullName',
      'organizations'
  ],

  comparePassword: function (password, user, cb) {
    bcrypt.compare(password, user.password, function (err, match) {
      if(err) return cb(err);
      cb(null, match);
    })
  },

  beforeCreate: function (user, cb) {
    bcrypt.genSalt(10, function (err, salt) {
      bcrypt.hash(user.password, salt, function () {}, function (err, hash) {
        if (err) {
          sails.log.error(err);
          return cb(err);
        }
        user.password = hash;
        cb(null, user);
      });
    });
  }
};
user2356169
  • 73
  • 2
  • 7

1 Answers1

0

Okay, I think I understand what you're doing. It would be a lot simpler to have the User belong to an organization directly.

Anyways, if I understood your model structure correctly, something like this should work:

getUserOrganizationsUsers: function (userId) {

    UserOrganization.find({ user_id: userId, deleted: null })
      .then(function (userOrgs) {
        // return array of organization IDs
        return _.map(userOrgs, function(org){
            return org.id; 
        });
      })
      .then(function (userOrgs) {
        Organization.find(userOrgs)
            .populate('users') // users is a collection of UserOrganization
            .exec(function(err, orgs){ // lookup organizations
            if(err) //handle error
            else {
                return _.flatten( // return basic array for next promise handler
                    _.map(orgs, function(org){ // for each organization
                        return _.map(org.users, function(user){ // return an array of user_ids
                            return user.user_id;
                        })
                    })
                )
            }
        })
      })
      .then(function(allUserOrgs){
          UserOrganization.find(allUserOrgs)
            .populate('user_id')
            .exec(function(err, userOrgsList){
                return _.map(userOrgsList, function(user){
                    return user.user_id;
                })
            })
      })
      .then(function(users){
          // users should be an array of all the users form allt he organizations that the current users belongs to
      })
},