Reputation: 2695
I have a handleCreate
function that takes care of taking some user data and inserting it into a database.
Inside the aliasArr.forEach()
loop I POST
into my DB new user instances for each element in the aliasArr
array. This particular code works as expected, if I check the DB, I will find the new members.
After saving the new members, I want to keep the members in the members
array so I can pass it along to another function.
For this, I'm doing members.push(memberAttributes);
but if I log the contents of members
I get the right amount of elements but the alias
property value is duplicated (all other properties should have the same value cause they are being added into the same role in a batch operation).
If I have two new users, say: xyz
and abc
, I get:
[
{alias: "abc", Role: "admin", "grantedBy": "someone"},
{alias: "abc", Role: "admin", "grantedBy": "someone"},
]
Instead of:
[
{alias: "xyz", Role: "admin", "grantedBy": "someone"},
{alias: "abc", Role: "admin", "grantedBy": "someone"},
]
Here's the code:
handleCreate = () => {
const { memberAttributes } = this.state;
const { role, createRoleMember } = this.props;
const roleArr = [];
roleArr.push(role);
const aliasArr = memberAttributes.alias.split(",");
let members = [];
//false hardcoded during debugging.
if (false /* await aliasIsAdmin(memberAttributes.alias, roleArr) */) {
this.setState({ userExists: true });
} else {
memberAttributes["Granted By"] = window.alias;
memberAttributes.Role = role;
memberAttributes.timestamp = Date.now().toString();
this.handleClose();
aliasArr.forEach((currAlias) => {
memberAttributes.alias = currAlias;
console.log("memberAttributes:", memberAttributes);
members.push(memberAttributes);
console.log("members", members);
const marshalledObj = AWS.DynamoDB.Converter.marshall(memberAttributes);
const params = {
TableName: "xxx",
Item: marshalledObj,
};
axios.post(
"https://xxx.execute-api.us-west-2.amazonaws.com/xxx/xxx",
params
);
});
}
createRoleMember(members); //passing members to this function to do more stuff.
};
I'm wondering if this issue is due to memberAttributes
being part of the component's state
.
Upvotes: 0
Views: 505
Reputation: 507
The problem here is that you are pushing references to the same object into the array after changing a value within that object. So whenever you make the change to memberAttributes.alias
, it's changing the alias to the most recent one. After that, all references to the same object (which in this case is every item in the members
array) present the new value in alias.
const obj = { alias: 'abc', role: 'role1' }
const arr = []
arr.push(obj)
obj.alias = 'new alias'
arr.push(obj)
for (var mem of arr) {
console.log(mem)
}
To fix it, you need to create a new object each time and push it onto the array instead, like so:
aliasArr.forEach((currAlias) => {
// Creates a new object in memory with the same values, but overwrites alias
const newMemberAttributes = Object.assign(memberAttributes, { alias: currAlias });
console.log("memberAttributes:", newMemberAttributes);
members.push(newMemberAttributes);
console.log("members", members);
...
}
Similarly, you can use the spread operator to create a deep copy of the object and then reassign alias.
aliasArr.forEach((currAlias) => {
// Creates a new object in memory with the same values, but overwrites alias
const newMemberAttributes = { ...memberAttributes };
newMemberAttributes.alias = currAlias
console.log("memberAttributes:", newMemberAttributes);
members.push(newMemberAttributes);
console.log("members", members);
...
}
Upvotes: 1