0

I have an object of data that is loaded from a database. A user can select options on the page and for each of those options that don't exist in the initial object, I need to create them.

I wrote up some psuedo code for what I am attempting here, its causing a memory issue though and crashing.

The goal here is that I iterate over each task > Roles array and check to see if theres any missing objects that need to be created. The object that need to be created come from selectedRoles.

Desired Outcome:

In the first task, it should create 3 roles as its currently empty. In the second task, it would create roles 1 and 3 because a role with the id of 2 already exists.

var tasks = [{
  "User": {
    "FirstName": "Joe",
    "LastName": "Dirt",
    "selected": false,
    "marked": false
  },
  "Tool": {
    "id": 31,
    "text": "Admin",
    "ToolID": "31",
    "ToolName": "Admin",
    "ToolSuite": "Enterprise Product"
  },
  "Roles": []
}, {
  "User": {
    "FirstName": "Bart",
    "LastName": "Simpson",
    "selected": false,
    "marked": false
  },
  "Tool": {
    "id": 35,
    "text": "Wordpress",
    "ToolID": "35",
    "ToolName": "Wordpress",
    "ToolSuite": "Enterprise Product"
  },
  "Roles": [{
    RoleName: 'Role 2',
    Role: 2,
    RoleID: 2
  }]
}];

// New selected roles from list
var selectedRoles = [1, 2, 3];

////////////////////////////////////////////////////////////////////////

/* 
  Loop over the configured tasks and
  if there is not an existing role
  matching a role id from "SelectedRoles",
  create a new role within that task.
*/

// Loop over the tasks
tasks.forEach((task) => {
    // If we have roles, loop over them
  if (task.Roles.length) {
    for (let i = 0; i < task.Roles.length; i++) {
            // If this roleID does not exist in our selectedRoles, create the task
      if(selectedRoles.indexOf(task.Roles[i].RoleID) >= 0){
        // Create this role and add it to our task
        task.Roles.push(createRole('Role ' + task.Roles[i].RoleID, task.Roles[i].RoleID, task.Roles[i].RoleID));
      }
    }
  }
});

console.log(tasks)

function createRole(RoleName, RoleID, Role){
    return {
    RoleName: RoleName,
    RoleID: RoleID,
    Role: Role
  }
}

Any thoughts on a more clean (and working) way to handle this?

1 Answer 1

1

var tasks = [{
  "User": {
    "FirstName": "Joe",
    "LastName": "Dirt",
    "selected": false,
    "marked": false
  },
  "Tool": {
    "id": 31,
    "text": "Admin",
    "ToolID": "31",
    "ToolName": "Admin",
    "ToolSuite": "Enterprise Product"
  },
  "Roles": []
}, {
  "User": {
    "FirstName": "Bart",
    "LastName": "Simpson",
    "selected": false,
    "marked": false
  },
  "Tool": {
    "id": 35,
    "text": "Wordpress",
    "ToolID": "35",
    "ToolName": "Wordpress",
    "ToolSuite": "Enterprise Product"
  },
  "Roles": [{
    RoleName: 'Role 2',
    Role: 2,
    RoleID: 2
  }]
}];

// New selected roles from list
var selectedRoles = [1, 2, 3];

////////////////////////////////////////////////////////////////////////

/* 
  Loop over the configured tasks and
  if there is not an existing role
  matching a role id from "SelectedRoles",
  create a new role within that task.
*/
tasks.forEach((task) => {
    if(task.Roles.length == 0){
      for(var i = 0; i < selectedRoles.length; i++){
        task.Roles.push(createRole('Role ' + selectedRoles[i], selectedRoles[i], selectedRoles[i]));
      }
    }
    else{
      var concatRoleArr = [];
      var roleIdArr = [];
      for(var i = 0; i < task.Roles.length; i++){
         roleIdArr.push(task.Roles[i].RoleID);
      }
      for(var i = 0; i < selectedRoles.length; i++){
        var roleIndex = roleIdArr.indexOf(selectedRoles[i]);
        if(roleIndex < 0){
          concatRoleArr.push(createRole('Role ' + selectedRoles[i], selectedRoles[i], selectedRoles[i]));
        }
      }
      task.Roles = task.Roles.concat(concatRoleArr);
    }
});

console.log(tasks);


function createRole(RoleName, RoleID, Role){
    return {
    RoleName: RoleName,
    RoleID: RoleID,
    Role: Role
  }
}

Here is your updated code with what you are after. We changed up your looping. We start with checking if there are any roles at all. If not, we loop through selectedRoles and add each one to the role.

If there are roles existing in the task, we create a new array (concatRoleArr), gather all roleIds into a new array, Then loop through selectedRoles again. If the array of existing role ids does not contain the currently looked at selectedRole (indexOf is -1), then add it to the new concatRoleArr, otherwise, continue. When we are done, concat the task.Roles array with concatRoleArr.

You were running into memory issues because your original code has an infinite loop. You add roles to task.Roles, so the loop just keeps on going because no end of task.Roles is ever reached with your for loop when you keep adding more to it. And it kept adding more because checking indexOf with >= 0 will be true if it EXISTS within the array, which your role always did because you were just looping through existing roles anyway. Checking < 0 checks if it DOES NOT EXIST, since it will return -1.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! Demo appears to work, integration should be the same :) - Appreciate it!

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.