Tengo una función handleCreate que se encarga de tomar algunos datos del usuario e insertarlos en una base de datos.

Dentro del bucle aliasArr.forEach() I POST en mi base de datos nuevas instancias de usuario para cada elemento en la matriz aliasArr. Este código en particular funciona como se esperaba, si reviso la base de datos, encontraré los nuevos miembros.

Después de guardar los miembros nuevos, quiero mantener los miembros en la matriz members para poder pasarlos a otra función.

Para esto, estoy haciendo members.push(memberAttributes); pero si registro el contenido de members obtengo la cantidad correcta de elementos pero el valor de la propiedad alias está duplicado (todas las demás propiedades deben tener el mismo valor porque se agregan al mismo rol en una operación por lotes).

Si tengo dos usuarios nuevos, diga: xyz y abc, obtengo:

[
    {alias: "abc", Role: "admin", "grantedBy": "someone"},
    {alias: "abc", Role: "admin", "grantedBy": "someone"},
]

En lugar de:

[
    {alias: "xyz", Role: "admin", "grantedBy": "someone"},
    {alias: "abc", Role: "admin", "grantedBy": "someone"},
]

Aquí está el código:

 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.
  };

Me pregunto si este problema se debe a que memberAttributes es parte del state del componente.

0
10110 31 ago. 2020 a las 21:34

1 respuesta

La mejor respuesta

El problema aquí es que está insertando referencias al mismo objeto en la matriz después de cambiar un valor dentro de ese objeto. Entonces, cada vez que realiza el cambio a memberAttributes.alias, cambia el alias al más reciente. Después de eso, todas las referencias al mismo objeto (que en este caso son todos los elementos de la matriz members) presentan el nuevo valor en 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)
}

Para solucionarlo, debe crear un nuevo objeto cada vez y, en su lugar, insertarlo en la matriz, así:

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);
   ...
}

De manera similar, puede usar el operador de extensión para crear una copia profunda del objeto y luego reasignar el 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);
   ...
}
1
Kevin Hoopes 31 ago. 2020 a las 18:55