user3142695
user3142695

Reputation: 17332

JS: Compare strings of an array with object fields

There is an object, which represents the role of an user:

const user = {
  isEditor: false,
  isAdmin: true,
  isTranslator: false
}

I need to pass some elements to a function an check if any of this role has a true value in the user object.

result = hasPermission(user, ['editor', 'admin']) // true
result = hasPermission(user, ['editor', 'translator']) // false

I've some problems with that, as the roles are named a bit differently. I thought also about using _.some() as I need to check for only one true value.

function hasPermission (user, roles) {
  roles.forEach(role => {
    user[role] // is not working as user keys named differently
  })
}

Upvotes: 1

Views: 77

Answers (4)

Jecfish
Jecfish

Reputation: 4189

Here is yet another solution.

const user = {
  isEditor: false,
  isAdmin: true,
  isTranslator: false
};

function hasPermission (user, roles) {
  const userRoles = Object
                      .entries(user)
                      .filter(([_, val]) => val)
                      .map(([key, _]) => key.replace('is', '').toLowerCase());
                      
  return roles.some(x => userRoles.includes(x));
  
}

console.log(hasPermission(user, ['editor', 'admin']));
console.log(hasPermission(user, ['editor', 'translator']));

Upvotes: 0

sjahan
sjahan

Reputation: 5940

Here is a solution the closest to your situation, without changing the shape of your objects and functions.

You can actually use some like this, it is quite simple:

const user = {
  isEditor: false,
  isAdmin: true,
  isTranslator: false
};

function hasPermission (user, roles) {
  return roles.some(role => user["is" + role[0].toUpperCase() + role.substring(1)]);
}

console.log(hasPermission(user, ['editor', 'admin']));
console.log(hasPermission(user, ['editor', 'translator']));

Hoping this will help you!

Upvotes: 1

guest271314
guest271314

Reputation: 1

You can use the same property names, Object.entries() to get an array of property, values pairs of the object and Array.prototype.some() and Array.prototype.includes() to check if the values match

const user = {
  isEditor: false,
  isAdmin: true,
  isTranslator: false
}

const hasPermission = (o, keys) =>
  Object.entries(o).some(([key, prop]) => prop && keys.includes(key));

let result = hasPermission(user, ["isEditor", "isAdmin"]);

console.log(result);

result = hasPermission(user, ["isEditor", "isTranslator"]);

console.log(result);

Upvotes: 0

MKougiouris
MKougiouris

Reputation: 2861

What you are doing is not the proper way to think about it.

A users role are not individual properties, rather a collection of roles. So your user object should be model like

const MyUser = {
  roles: ["Admin","Editor"]
}

So then you can check if a user has a given role by working with a function like so :

function UserHasAnyRole(user,roleKeys)
{
    if(user && user.roles && roleKeys && roleKeys.length)
    {
        return user.roles.filter(function(r){
            return roleKeys.filter(function(k){ return k == r;}).length>0; 
        }).length > 0;

    }       
    return false;    
}

var neededRoles = ["Admin","Translator"];

if(UserHasAnyRole(MyUser,neededRoles))
{
// do stuff
}

This way of thinking about it scales much better, as individual properties is not a sustainable way in the long term

EDIT: to account for arrray of input roles. This is not tested tho, so there might be some syntax errors in there, but you get the idea...

Upvotes: 3

Related Questions