JSFiddle - React, Tailwind, and code Playground

by Castle Kerr

JavaScript

var data = '[{"id":1,"title":"adminGroup","users":[{"id":1,"username":"admin","password":"...","groups":[1]},{"id":31,"username":"user78","password":"...","groups":[1]},{"id":3,"username":"ali","password":"...","groups":[{"id":2,"title":"newsWriterGroup","users":[{"id":14,"username":"staff1","password":"...","groups":[{"id":1005,"title":"FileManagerAccessGroup","users":[{"id":25,"username":"test1","password":"...","groups":[1005]},14]},2]},3]},1]}]}]';
var groupCache = {}, userCache = {};

function Group(group) {
  this.id = group.id;
  this.title = group.title;
  this.users = [];
  groupCache[this.id] = this;
  group.users.forEach(this.addUser.bind(this));
}
Group.prototype.addUser = function(user) {
  this.users.push(typeof user === 'number' ? userCache[user] : new User(user));
}

function User(user) {
  this.id = user.id;
  this.username = user.username;
  this.password = user.password;
  this.groups = [];
  userCache[this.id] = this;
  user.groups.forEach(this.addGroup.bind(this));
}
User.prototype.addGroup = function(group) {
  this.groups.push(
    typeof group === 'number' 
      ? groupCache[group]
      : new Group(group)
  );
}

// begins the recursion
JSON.parse(data).forEach(function(group) { new Group(group) });

function stopCircularWithId(key, value) {
  return (key === 'users' || key === 'groups')
    ? value.map(function(u) { return u.id })
    : value;
}
console.log('groups:', JSON.stringify(groupCache, stopCircularWithId, 4));
console.log('users:', JSON.stringify(userCache, stopCircularWithId, 4));