Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

156
Vistas
Push into array of objects with nested level using spread operator

I am having an object containing array of objects with following format which is stored in a state

const [value, setVal] = useState({ available : [], done: [] })

done is an array of objects with following structure

[{col: "test", val: ["abc","xyz"]}]

I am writing a function that takes field and value as input parameters. If the field is present in done array, then I need to push it inside its corresponding val array. Else I need to create a new object and then push it inside. How can I achieve this?

How can I set the state in both the cases?Code that I tried is below

function update(field, value){
    const filterIndex = value.done.findIndex((obj) => field === obj.col);
    if (filterIndex > -1) {
      value.done[filterIndex].val.push(value);
    } else {
      setVal({
        ...value,
        done: [
          ...value.done,
          {
            col: field,
            val: [value],
          }
        ]
      });
    }
} 

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

You should use a separate variable name for the state instead of value since the function has a local variable also called value.

Try like below.

const [values, setVals] = useState({ available: [], done: [] })

function update(field, value) {
  const filterIndex = values.done.findIndex((obj) => field === obj.col);
  if (filterIndex > -1) {
    // get a copy of the previous state done values
    const updatedDone = [...values.done];
    // update the new value in the copy of the array
    updatedDone[filterIndex].val.push(value);
    // update the state
    setVals((prevValue) => ({ ...prevValue, done: updatedDone }));
  } else {
    // add the new entry for the new filed with the value
    setVals((prevValue) => ({
      ...prevValue,
      done: [
        ...prevValue.done,
        {
          col: field,
          val: [value],
        },
      ],
    }));
  }
}
about 4 years ago · Juan Pablo Isaza Denunciar

0

This may be one possible solution:

Code Snippet

const stateVal = { available : [], done: [{col: "test", val: ["abc","xyz"]}] };

const updateStateVal = (sv, field, value) => ({
  ...sv,
  done: (
    sv.done.map(ob => ob.col).includes(field)
    ? sv.done.map(ob => (
      ob.col === field
      ? {...ob, val: ob.val.concat([value])}
      : {...ob}
    ))
    : sv.done.concat([{ col: field, val: [value] }])
  )
});

console.log('existing col test: ', updateStateVal(stateVal, 'test', 'def'));
console.log('non-exist col test2: ', updateStateVal(stateVal, 'test2', 'def'));

How to use

setVal(prev => ({...updateStateVal(prev, field, value)}));

Explanation

  • The objective is to insert value based on presence/absence of field in done.

  • The method updateStateVal takes 3 params, the prev-state sv, the field & the value

  • Use ... spread operator to list down all props of prev (ie, sv) as-is

  • Now, override the done prop

  • First check if the prev-state's done already has field by matching with the cols from each array-element.

  • This is done using .map() in conjunction with .includes()

  • If found, iterate through the done array.

    For the array element where col matches field, .concat the existing val array with value. All other elements go as-is.

  • If not found, simply .concat a single-element array ([{ col: field, val: [value]}]) to existing done array.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda