user3052526
user3052526

Reputation: 681

AngularJS Array Comparison

I have got the following array of Usernames

Usernames = [
  {
    "id": 1,
    "userName": "Jack",
    "description": "jack is a nice guy",
    "userRoleIds": [
      1
    ]
  },
  {
    "id": 2,
    "userName": "Caroline",
    "description": "Good girl",
    "userRoleIds": [
      2,3
    ]
  },
  {
    "id": 3,
    "userName": "Smith",
    "description": "Smithyyyy",
    "userRoleIds": [
      1,2
    ]
  }
]

And an array of userRoles.

userRoles = [
  {
    id: 1,
    roleName: "Admin"
  },
  {
    id: 2,
    roleName: "Tester"
  },
  {
    id: 3,
    roleName: "Developer"
  }
]

What i want to get done is first concat the arrays in in Usernames and userRoles to get the following result.

 Usernames = [
      {
        "id": 1,
        "userName": "Jack",
        "description": "jack is a nice guy",
        "userRoleIds": [
          {
            "id": 1,
            "roleName" : "Admin"
          }
        ]
      },
     {
    "id": 2,
    "userName": "Caroline",
    "description": "Good girl",
    "userRoleIds": [
         {
            "id": 2,
            "roleName" : "Tester"
          },
          {
            "id": 3,
            "roleName" : "Developer"
          }
    ]
   },...

The second thing i want is to be able to filter for the roleName and userName seperated by pipe signs. As in type something in a text box that searches for userName and roleName for example.

if i type

Caroline, Tester

The result will be

result = [
  {
    "id": 2,
    "userName": "Caroline",
    "description": "Good girl",
    "userRoleIds": [
      2,3
    ]
  },
  {
    "id": 3,
    "userName": "Smith",
    "description": "Smithyyyy",
    "userRoleIds": [
      1,2
    ]
  }
]

What is the best practice for achieving this?

Thanks

Upvotes: 0

Views: 85

Answers (3)

Redu
Redu

Reputation: 26161

I would do with pure JS like this. It won't take more than a single assignment line each.

var Usernames = [
  {
    "id": 1,
    "userName": "Jack",
    "description": "jack is a nice guy",
    "userRoleIds": [
      1
    ]
  },
  {
    "id": 2,
    "userName": "Caroline",
    "description": "Good girl",
    "userRoleIds": [
      2,3
    ]
  },
  {
    "id": 3,
    "userName": "Smith",
    "description": "Smithyyyy",
    "userRoleIds": [
      1,2
    ]
  }
],
userRoles = [
  {
    id: 1,
    roleName: "Admin"
  },
  {
    id: 2,
    roleName: "Tester"
  },
  {
    id: 3,
    roleName: "Developer"
  }
],
modified = Usernames.reduce((p,c) => (c.userRoleIds = c.userRoleIds.map(e => e = userRoles.find(f => f.id == e)),p.concat(c)),[]),
   query = ["Caroline","Tester"],
filtered = modified.filter(f => query.includes(f.userName) || f.userRoleIds.some(e => query.includes(e.roleName)));
console.log(JSON.stringify(modified,null,2));
console.log(JSON.stringify(filtered,null,2));

Upvotes: 1

fyasir
fyasir

Reputation: 2970

You can use lodash to achieve this.

var role = _.find(userRoles, function(role) { 
            return role.roleName == 'Tester'; 
        });
_.find(Usernames, function(user) { 
    return user.userName == 'Caroline' || _.indexOf(user.userRoleIds, role.id)>=0; 
});

Upvotes: 0

Pablo Adoue
Pablo Adoue

Reputation: 106

Here is how I would do it. I prefer using services and take advantage of their functions to keep code clean.

app.service('UserService', function (PermisionsServices) {
    var self = {
        'list': [],
        'load': function (Users) {//Pass your array of Users
            angular.forEach(Users, function (user) {
                angular.forEach(user.userRoleIds, function (role) {
                    self.user.userRolesIds.push(PermisionsServices.get(role));
                });
                self.list.push(user);
            });
        }, 'get': function (id) {
            for (var i = 0; i < self.list.length; i++) {
                var obj = self.list[i];
                if (obj.id == id) {
                    return obj;
                }
            }
        }
    };
    return self;
});

app.service('PermisionsServices', function () {
    var self = {
        'list': [],
        'load': function (permisions) {//Pass your array of permisions
            angular.forEach(permisions, function (permision) {
                self.list.push(permision);
            });
        }, 'get': function (id) {
            for (var i = 0; i < self.list.length; i++) {
                var obj = self.list[i];
                if (obj.id == id) {
                    return obj;
                }
            }
        }
    };
    return self;
});

Afterwards, you can use it on your controller: $scope.users=UserService;

And access each of the users as a separate object which can have multiple object permisions.

NOTE: Building the service (populating it) will of course depend on your app logic and controller, you could just easily remove the "load" function and just hardcode the list object by copy and pasting your arrays.

This is the approach I use to load data from API via resource.

Regards

Edit: For use on the UI, you would just call:

<div ng-repeat='user in users.list'>
  {{user.name}} has {{user.permissions}}
</div>

as the object information is already contained within it.

Edit 2: If you want to search your data, then you can just add a filter like this:

<div ng-repeat='user in users.list | filter: filterList'>
      {{user.name}} has {{user.permissions}}
</div>

And then on the controller:

$scope.filterList = function (user) {
        if ($scope.filterTextBox) {
            return user.name.indexOf($scope.filterTextBox) == 0;
        }

        return true;
    }

Hope this works for you

Upvotes: 1

Related Questions