0

I have an empty object structured like so :

let users = {
  "type1": {
      "group1": {
          "role1": {}
      },
      "group2": {
          "role2": {},
          "role3": {},
          "role4": {}
      },
  },
  "type2": {
      "group1": {
          "role1": {}
      },
      "group2": {
          "role2": {}
      },
      "group3": {
          "role3": {},
          "role4": {}
      }
  }
};

I am then fetching my users with an associated type, group and role for each one. I would like to dynamically add my users to my object above in the right type/group/role combination as they are stored in variables.

I tried something like this but this is wrong:

fetchedUsers.forEach(user => {
  users[user.type][user.group][user.role].push(user.email);
})

Is there a way to do this similar to what I tried ?

6
  • 2
    Those roles are (empty) objects. You can't push something into an object, only an array since push is an array method. Commented May 12, 2022 at 13:18
  • 1
    The closest analog to Array#push is Object.assign though it doesn't modify the target object in place, so you will still need to do some reconstructive work. Commented May 12, 2022 at 13:20
  • I know I can't I am searching for the closest way to do this but with an object @Andy Commented May 12, 2022 at 13:27
  • I was just pointing out why your code doesn't work. It would help to see what your expect your updated object should look like. Should a role look like this: role: { name: 'Bob', role: 'admin' } where there is only one role assigned to it, or role: [{ name: 'Bob', role: 'admin'}, { name: 'Jo', role: 'user' }] where there are many roles assigned to an array. How you want your output to look depends solely on what that structure is meant to look like. @Ryan Commented May 12, 2022 at 13:40
  • 1
    @Ryan I added a version with one email per role, keyed emails and an array of emails Commented May 12, 2022 at 14:09

2 Answers 2

4

You cannot push to an object. Your role is not an array

let users = { 
"type1": { "group1": { "role1": {} },
           "group2": { "role2": {}, "role3": {}, "role4": {}},},
"type2": { "group1": { "role1": {} },
           "group2": { "role2": {}},
           "group3": { "role3": {}, "role4": {}}}};

const fetchedUsers = [
  {"type":"type1","group": "group2", "role":"role3", "email":"[email protected]"},
  {"type":"type2","group": "group1", "role":"role1", "email":"[email protected]"}
];

fetchedUsers.forEach(
  ({type,group,role,email}) => users[type][group][role].email = email
);
console.log(users)

If you have more than one email per role, you need to make some keys

let users = { 
"type1": { "group1": { "role1": {} },
           "group2": { "role2": {}, "role3": {}, "role4": {}},},
"type2": { "group1": { "role1": {} },
           "group2": { "role2": {}},
           "group3": { "role3": {}, "role4": {}}}};

const fetchedUsers = [
  {"type":"type1","group": "group2", "role":"role3", "email":"[email protected]"},
  {"type":"type2","group": "group1", "role":"role1", "email":"[email protected]"},
  {"type":"type2","group": "group1", "role":"role1", "email":"[email protected]"}
];

fetchedUsers.forEach(
  ({type,group,role,email}) => {
    const currentRole = users[type][group][role]
    const len = Object.entries(currentRole).length
    currentRole[`email${len}`] = email
});
console.log(users)

or use an array

let users = { 
"type1": { "group1": { "role1": {} },
           "group2": { "role2": {}, "role3": {}, "role4": {}},},
"type2": { "group1": { "role1": {} },
           "group2": { "role2": {}},
           "group3": { "role3": {}, "role4": {}}}};

const fetchedUsers = [
  {"type":"type1","group": "group2", "role":"role3", "email":"[email protected]"},
  {"type":"type2","group": "group1", "role":"role1", "email":"[email protected]"},
  {"type":"type2","group": "group1", "role":"role1", "email":"[email protected]"}
];

fetchedUsers.forEach(
  ({type,group,role,email}) => {
    const currentRole = users[type][group][role]
    currentRole.emails = currentRole.emails || []
    currentRole.emails.push(email)
});
console.log(users)

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

Comments

2

Since users[user.type][user.group][user.role] is an object you can't use push()

If you initialise the empty role structures as arrays it should work.

let users = {
  "type1": {
      "group1": {
          "role1": []
      },
      "group2": {
          "role2": [],
          "role3": [],
          "role4": []
      },
  },
  "type2": {
      "group1": {
          "role1": []
      },
      "group2": {
          "role2": []
      },
      "group3": {
          "role3": [],
          "role4": []
      }
  }
};

3 Comments

This works well indeed, but I also need a way to keep roles as an object unhappily...
Alright. Then I'd probably do something like users[user.type][user.group][user.role][user.email] = user.email this will sett each row in a role like {[email protected]: '[email protected]', [email protected]: '[email protected]'} etc.
Alright yes thank you this works as I wanted !

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.