1

I am writing a permission function in angular js factory method which checks user role. if user object have such role then result should be true else it should return false. my user object is:

administrator:true 
company_admin:true 
registered:true 
manager:true
contact:"987654321" email:"abcd@gmail.com" name:"Anand"

And My Permission function in app model factory is:

$appModel.checkPermission:function($role, $requireAll) {
            var data = $rootScope.authUser;
            if (angular.isArray($role)) {
                angular.forEach($role, function (value, key) {
                    var hasRole =  $appModel.checkPermission(value); //Recursive Function
                    if (hasRole && !$requireAll) {
                        return true;
                    } else if (!hasRole && $requireAll) {
                        return false;
                    }
                });
                return $requireAll;
            } else {
                if (data.hasOwnProperty($role) && data[$role])
                    return true;
            }
            return false;
        }

There are following cases which i am checking: 1. If there is multiple role in that array with 'required all' condition, then check that multiple roles present in user object and return true otherwise false.

 $result= $appModel.checkPermission([registered, company_admin], true);

2. If there is multiple role in that array, then check those multiple roles in are present in user object and if any role get matched, then return true otherwise return false.

 $result= $appModel.checkPermission([administrator, company_admin,manager,agent], false);

3. If there is single role in that array, then check that role is present in user object and if that role get matched, then return true otherwise return false.

  $result= $appModel.checkPermission(register, false);

The above code is running fine for single role checking but in case of multiple role checking with 'required all' or not 'required all' condition, it does not work properly and return false.

Hemant
  • 81
  • 9

1 Answers1

0

I don't believe you can break out of AngularJS's forEach using a return as it's as alternative to similar to forEach.

From MDN:

There is no way to stop or break a forEach() loop other than by throwing an exception.

After your first return true the loop is still carrying on, not actually causing the inner return statements to be established, falling out of the loop into your return $requireAll; which, in your examples, is the false statement you are seeing.

You can see this by placing debugging before each return statement, and seeing them continuing to fire after a return.

By using some and every I rewrote your logic to avoid using forEach:

var results = $role.map($appModel.checkPermission);
return requireAll
  ? results.every(function(item) {return item;})
  : results.some(function(item) {return item;})
} else {
  return (data.hasOwnProperty(role) && data[role]);
}

The following snippet shows this code working in simply JavaScript.

var roleChecker = function(role, requireAll) {
  var data = {
    administrator: true,
    company_admin: true,
    registered: true,
    manager: true,
  };
  
  if( Object.prototype.toString.call(role) === '[object Array]' ) {
    var results = role.map(roleChecker);
    
    return requireAll ? results.every(function(item) {return item;})
      : results.some(function(item) {return item;})
  } else {
    return (data.hasOwnProperty(role) && data[role]);
  }
  
};

console.log(roleChecker(['administrator', 'manager'], false));
console.log(roleChecker(['administrator', 'company_admin', 'fake_role'], true));
console.log(roleChecker(['administrator', 'company_admin'], true));
console.log(roleChecker('administrator', false));
console.log(roleChecker('fake_role', false));
user2340824
  • 2,142
  • 2
  • 15
  • 19
  • Also, your last line `if (data.hasOwnProperty(role) && data[role])` will fail if the role doesn't exist. I have resolved this by returning the conditional check – user2340824 May 20 '17 at 09:19
  • Thanks buddy!. It worked exceptionally well. It had been very hectic for me to deal with it since last two days. You saved a lot of time for me. Thanks a ton. @user2340824 – Hemant May 20 '17 at 10:55
  • Hello Bro, @user2340824 can you please take a look at the link of a question I am giving below. Since I have not got any other way of contacting you, so just putting this comment as a message. https://stackoverflow.com/questions/44538967/angularjs-multiple-dropzone-for-image-upload-on-a-single-page – Hemant Jun 14 '17 at 09:03