-1

I have an obj that looks like this.

let obj= {
  title:"my form",
  endTIme:"2/20/22",
  mainList:[
    {
      type:"multiple", 
      checked:false,
      multiple:[
         {
           optionCheck: false,
           optionAnswer:""
         }
      ]
    }
  ]
}

I also have a button that every time I click, I want the obj fields to retain all its values only that the multiple array field should append a new object . But I cant seem to figure it out. Please I really need help

I tried cloning using spread operator and I wasn't getting the result I want as I learnt that spread operator is best used for shallow cloning

let newObj= {
 ...obj
  mainList:[
     ...obj.mainList,
    {
      multiple:[
         {
           optionCheck: false,
           optionAnswer:""
         }
      ]
    }
  ]
}

And this ends up duplicating the mainList instead.

What I want my result to like is this when I click the button once.

let obj = {
  title: "my form",
  endTIme: "2/20/22",
  mainList: [{
    type: "multiple",
    checked: false,
    multiple: [
    {
      optionCheck: false,
      optionAnswer: ""
    }, 
    {
      optionCheck: false,
      optionAnswer: ""
    }]
  }]
};
adiga
  • 34,372
  • 9
  • 61
  • 83
  • is it always the same object being added to the array? – Jorge Guerreiro Oct 28 '22 at 08:25
  • Why aren't you just pushing to `multiple` array? Is there a reason for creating a new object instead of just mutating this object? You haven't tagged react here. – adiga Oct 28 '22 at 08:27

4 Answers4

0

If you want to stay immutable and still use spread operator:

const newObj = {
  ...obj,
  mainList: [
    {
      ...obj.mainList,
      multiple: [
        ...obj.mainList.multiple,
        {
          optionAnswer: "",
          optionCheck: false,
        },
      ],
    },
  ],
};
0

Just use array.push

let obj= {
  title:"my form",
  endTIme:"2/20/22",
  mainList:[
    {
      type:"multiple", 
      checked:false,
      multiple:[
         {
           optionCheck: false,
           optionAnswer:""
         }
      ]
    }
  ]
}

obj.mainList[0].multiple.push( {
           optionCheck: false,
           optionAnswer:""
         });
         
console.log(obj)
jitender
  • 10,238
  • 1
  • 18
  • 44
0

Yeah, its just a case of continuing to use the spread operator:

const newObj= {
 ...obj
  mainList:[
     ...obj.mainList,
    {
      multiple:[
         ...obj.mainList.multiple,
         {
           optionCheck: false,
           optionAnswer:""
         }
      ]
    }
  ]
}

The alternative is keeping the let as you have already and targeting the keys you're updating:

let newObj = {
 ...obj
};

newObj["mainList"]["multiple"] = newObj["mainList"]["multiple"].concat({
  optionCheck: false,
  optionAnswer:""
});

// Or if you want it at the begining
newObj["mainList"]["multiple"] = [{
  optionCheck: false,
  optionAnswer:""
}].concat(...newObj["mainList"]["multiple"]);


// Another way
newObj["mainList"]["multiple"].push({
  optionCheck: false,
  optionAnswer:""
})

EDIT: As another answer has also said, you can use push (see above)

Harrison
  • 1,654
  • 6
  • 11
  • 19
0

If you want to deep clone the object, you can use structuredClone() (https://developer.mozilla.org/en-US/docs/Web/API/structuredClone)

// Your original object
let obj= {
  title:"my form",
  endTIme:"2/20/22",
  mainList:[
    {
      type:"multiple", 
      checked:false,
      multiple:[
         {
           optionCheck: false,
           optionAnswer:""
         }
      ]
    }
  ]
}

// Cloning the object
const newObj = structuredClone(obj);

// push new item to the cloned object
newObj.mainList[0].multiple.push(
  {
    optionCheck: false,
    optionAnswer:""
  }
)
notrev
  • 665
  • 1
  • 5
  • 16