3

I'm trying to make a simple ACL just for practice.

I want to loop through my object data and if my currentViewer has a parent I want to add his path (access in my object) to arrayAccess.

So if my viewer is user his accessArray should be ["", home], if he's admin it would be ["", home, user] and if he's a guest it will be only [""].

How to do it in a recursive way, so I don't have to create thousands of for loops?

I was trying calling a checkParent() inside my checkParent(), but it only makes my loop infinitive. I'm sorry if it's a silly question, I'm very beginning in JS.

var currentViewer = "user";
var data = {
  users: [{
      role: "guest",
      access: ""
    },
    {
      role: "user",
      access: "home",
      parent: "guest"
    },
    {
      role: "admin",
      access: "user",
      parent: "user"
    }
  ]
};

var accessArray = [];

function checkRole() {
  var users = data.users;
  for (var i = 0; i < users.length; i++) {
    if (currentViewer === users[i].role) {
      accessArray.push(users[i].access);
      console.log(accessArray);

      function checkParent() {
        if (users[i].parent) {
          for (var j = 0; j < users.length; j++) {
            if (users[i].parent === users[j].role) {
              accessArray.push(users[j].access);
              console.log(accessArray);
            }
          }
        }
      };
      checkParent();
    }
  };
};
checkRole();

4 Answers 4

1

You can try this:

var data = { 
    users : [
        { role:"guest" , access:"" },
        { role:"user" , access:"home", parent: "guest" },
        { role:"admin" , access:"user", parent: "user" }
    ]
};

var currentUser = "admin";

var arr = [];//array that you need

var defineAccess = function(item){
    if(item.parent){
        var index = data.users.map(function(e) { return e.role; }).indexOf(item.parent);
        defineAccess(data.users[index]); //recursive calling
        arr.push(data.users[index].access);
    }
}

data.users.forEach(function(item){
    if(currentUser === item.role){
        arr.push(item.access);
        defineAccess(item);
    }   
})

console.log(arr); //final output array
Sign up to request clarification or add additional context in comments.

2 Comments

thank you, but your array for admin returns only ["home", "user"] instead of ["", "home", "user"]
@Sara: my bad, please check my updated answer. It works correctly now
1

There are a bunch of ways to do it. Simple way is just make a hash for easy look up and reference the parents on a loop and push.

var data = { users : [
    { role:"guest" , access:"" },
    { role:"user" , access:"home", parent: "guest" },
    { role:"admin" , access:"user", parent: "user" }
    ]
};

var roleHash = data.users.reduce(function(o, i) {
  o[i.role] = i;
  return o;
}, {});

function getAccessRoles(roleKey) {
  var role = roleHash[roleKey];
  var roles = [role.access];
  while (role.parent) {
    role = roleHash[role.parent];
    roles.unshift(role.access);
  }
  return roles;
}

console.log("admin", getAccessRoles("admin"));
console.log("user", getAccessRoles("user"));
console.log("guest", getAccessRoles("guest"));

Comments

1

I don't think "recursiveness" should be a goal on its own... Why not create a Map of roles and their properties and use the parent property to retrieve a new item from this map, until you can't?

var data = {
  users: [{
      role: "guest",
      access: ""
    },
    {
      role: "user",
      access: "home",
      parent: "guest"
    },
    {
      role: "admin",
      access: "user",
      parent: "user"
    }
  ]
};

var roles = new Map(data.users.map(u => [u.role, u]));

var getAccess = function(role) {
  var access = [];
  var current = roles.get(role);

  while (current) {
    access.push(current.access);
    current = roles.get(current.parent);
  }

  return access.reverse();
}

console.log("guest", getAccess("guest"))
console.log("user", getAccess("user"))
console.log("admin", getAccess("admin"))

Comments

0

build an object model first,then the problem is simple.

var data = {
    users: [
        {
            role: "guest",
            access: ""
        },
        {
            role: "user",
            access: "home",
            parent: "guest"
        },
        {
            role: "admin",
            access: "user",
            parent: "user"
        }
    ]
};
var users = data.users.reduce(function (roles, user) {
    roles[user.role] = user;
    return roles;
}, {});
var accessList = data.users.map(function (user) {
    var all = [];
    do {
        all.unshift(user.access);
        user = users[user.parent];
    } while (user);
    return all;
});

console.log(accessList);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.